Socket心跳包机制
生活随笔
收集整理的這篇文章主要介紹了
Socket心跳包机制
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
心跳包的發(fā)送,通常有兩種技術
方法1:應用層自己實現(xiàn)的心跳包
由應用程序自己發(fā)送心跳包來檢測連接是否正常,大致的方法是:服務器在一個 Timer事件中定時 向客戶端發(fā)送一個短小精悍的數(shù)據包,然后啟動一個低級別的線程,在該線程中不斷檢測客戶端的回應, 如果在一定時間內沒有收到客戶端的回應,即認為客戶端已經掉線;同樣,如果客戶端在一定時間內沒 有收到服務器的心跳包,則認為連接不可用。
方法2:TCP的KeepAlive保活機制
因為要考慮到一個服務器通常會連接多個客戶端,因此由用戶在應用層自己實現(xiàn)心跳包,代碼較多 且稍顯復雜,而利用TCP/IP協(xié)議層為內置的KeepAlive功能來實現(xiàn)心跳功能則簡單得多。 不論是服務端還是客戶端,一方開啟KeepAlive功能后,就會自動在規(guī)定時間內向對方發(fā)送心跳包, 而另一方在收到心跳包后就會自動回復,以告訴對方我仍然在線。 因為開啟KeepAlive功能需要消耗額外的寬帶和流量,所以TCP協(xié)議層默認并不開啟KeepAlive功 能,盡管這微不足道,但在按流量計費的環(huán)境下增加了費用,另一方面,KeepAlive設置不合理時可能會 因為短暫的網絡波動而斷開健康的TCP連接。并且,默認的KeepAlive超時需要7,200,000 MilliSeconds, 即2小時,探測次數(shù)為5次。對于很多服務端應用程序來說,2小時的空閑時間太長。因此,我們需要手工開啟KeepAlive功能并設置合理的KeepAlive參數(shù)。
以上轉自網絡。
心跳包機制 ??跳包之所以叫心跳包是因為:它像心跳一樣每隔固定時間發(fā)一次,以此來告訴服務器,這個客戶端還活著。事實上這是為了保持長連接,至于這個包的內容,是沒有什么特別規(guī)定的,不過一般都是很小的包,或者只包含包頭的一個空包。
???在TCP的機制里面,本身是存在有心跳包的機制的,也就是TCP的選項:SO_KEEPALIVE。系統(tǒng)默認是設置的2小時的心跳頻率。但是它檢查不到機器斷電、網線拔出、防火墻這些斷線。而且邏輯層處理斷線可能也不是那么好處理。一般,如果只是用于保活還是可以的。
???心跳包一般來說都是在邏輯層發(fā)送空的echo包來實現(xiàn)的。下一個定時器,在一定時間間隔下發(fā)送一個空包給客戶端,然后客戶端反饋一個同樣的空包回來,服務器如果在一定時間內收不到客戶端發(fā)送過來的反饋包,那就只有認定說掉線了。
???其實,要判定掉線,只需要send或者recv一下,如果結果為零,則為掉線。但是,在長連接下,有可能很長一段時間都沒有數(shù)據往來。理論上說,這個連接是一直保持連接的,但是實際情況中,如果中間節(jié)點出現(xiàn)什么故障是難以知道的。更要命的是,有的節(jié)點(防火墻)會自動把一定時間之內沒有數(shù)據交互的連接給斷掉。在這個時候,就需要我們的心跳包了,用于維持長連接,保活。
???在獲知了斷線之后,服務器邏輯可能需要做一些事情,比如斷線后的數(shù)據清理呀,重新連接呀……當然,這個自然是要由邏輯層根據需求去做了。
???總的來說,心跳包主要也就是用于長連接的保活和斷線處理。一般的應用下,判定時間在30-40秒比較不錯。如果實在要求高,那就在6-9秒。
心跳檢測步驟:
1客戶端每隔一個時間間隔發(fā)生一個探測包給服務器
2客戶端發(fā)包時啟動一個超時定時器
3服務器端接收到檢測包,應該回應一個包
4如果客戶機收到服務器的應答包,則說明服務器正常,刪除超時定時器
5如果客戶端的超時定時器超時,依然沒有收到應答包,則說明服務器掛了
轉自:http://blog.sina.com.cn/s/blog_a459dcf5010153m5.html
根據上面的介紹我們可以知道對端以一種非優(yōu)雅的方式斷開連接的時候,我們可以設置SO_KEEPALIVE屬性使得我們在2小時以后發(fā)現(xiàn)對方的TCP連接是否依然存在。
具體操作:
??? //設置KeepAlive??? ?
?? 1、 BOOL?? bKeepAlive?? =?? TRUE;??? ?
?? ?int nRet=::setsockopt(sockClient,SOL_SOCKET,SO_KEEPALIVE,(char*)&bKeepAlive,sizeof(bKeepAlive));??? ?
?? ?if(nRet!=0)?? ?
?? ?{??? ?
?? ?????AfxMessageBox("出錯");
?? ??? ?return?? ;
?? ?}??? ?
?? ?
?? 2、感覺兩小時時間太長可以自行設定方法1
//設置KeepAlive檢測時間和次數(shù)??? ?
?? ?tcp_keepalive??? inKeepAlive?? =?? {0};?? //輸入參數(shù)??? ?
?? ?unsigned?? long?? ulInLen?? =?? sizeof(tcp_keepalive );??????? ?
?? ?
?? ?tcp_keepalive??? outKeepAlive?? =?? {0};?? //輸出參數(shù)??? ?
?? ?unsigned?? long?? ulOutLen?? =?? sizeof(tcp_keepalive );??????? ?
?? ?
?? ?unsigned?? long?? ulBytesReturn?? =?? 0;??? ?
?? ?
?? ?//設置socket的keep?? alive為10秒,并且發(fā)送次數(shù)為3次??? ?
?? ?inKeepAlive.onoff?? =?? 1;????? ?
?? ?inKeepAlive.keepaliveinterval?? =?? 4000;?? //兩次KeepAlive探測間的時間間隔??? ?
?? ?inKeepAlive.keepalivetime?? =?? 1000;?? //開始首次KeepAlive探測前的TCP空閉時間??? ?
?? ?
?? ?nRet=WSAIoctl(sockClient,????? ?
?? ??? ?SIO_KEEPALIVE_VALS,??? ?
?? ??? ?(LPVOID)&inKeepAlive,??? ?
?? ??? ?ulInLen,??? ?
?? ??? ?(LPVOID)&outKeepAlive,??? ?
?? ??? ?ulOutLen,??? ?
?? ??? ?&ulBytesReturn,??? ?
?? ??? ?NULL,??? ?
?? ??? ?NULL);??? ?
?? ?if(SOCKET_ERROR?? ==?? nRet)??? ?
?? ?{??? ?
?? ??? ?AfxMessageBox("出錯");
?? ??? ?return;?? ?
?? ?}??
3、感覺兩小時時間太長可以自行設定方法2
因此我們可以得到
? ? int? ?? ?? ?? ?? ???keepIdle = 6;
? ? int? ?? ?? ?? ?? ???keepInterval = 5;
? ? int? ?? ?? ?? ?? ???keepCount = 3;
? ? Setsockopt(listenfd, SOL_TCP, TCP_KEEPIDLE, (void *)&keepIdle, sizeof(keepIdle));
? ? Setsockopt(listenfd, SOL_TCP,TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));
? ? Setsockopt(listenfd,SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));
詳見:http://blog.csdn.net/gavin1203/article/details/5290609
對setsockopt的操作,詳見:http://www.cnblogs.com/hateislove214/archive/2010/11/05/1869886.html
方法1:應用層自己實現(xiàn)的心跳包
由應用程序自己發(fā)送心跳包來檢測連接是否正常,大致的方法是:服務器在一個 Timer事件中定時 向客戶端發(fā)送一個短小精悍的數(shù)據包,然后啟動一個低級別的線程,在該線程中不斷檢測客戶端的回應, 如果在一定時間內沒有收到客戶端的回應,即認為客戶端已經掉線;同樣,如果客戶端在一定時間內沒 有收到服務器的心跳包,則認為連接不可用。
方法2:TCP的KeepAlive保活機制
因為要考慮到一個服務器通常會連接多個客戶端,因此由用戶在應用層自己實現(xiàn)心跳包,代碼較多 且稍顯復雜,而利用TCP/IP協(xié)議層為內置的KeepAlive功能來實現(xiàn)心跳功能則簡單得多。 不論是服務端還是客戶端,一方開啟KeepAlive功能后,就會自動在規(guī)定時間內向對方發(fā)送心跳包, 而另一方在收到心跳包后就會自動回復,以告訴對方我仍然在線。 因為開啟KeepAlive功能需要消耗額外的寬帶和流量,所以TCP協(xié)議層默認并不開啟KeepAlive功 能,盡管這微不足道,但在按流量計費的環(huán)境下增加了費用,另一方面,KeepAlive設置不合理時可能會 因為短暫的網絡波動而斷開健康的TCP連接。并且,默認的KeepAlive超時需要7,200,000 MilliSeconds, 即2小時,探測次數(shù)為5次。對于很多服務端應用程序來說,2小時的空閑時間太長。因此,我們需要手工開啟KeepAlive功能并設置合理的KeepAlive參數(shù)。
以上轉自網絡。
心跳包機制 ??跳包之所以叫心跳包是因為:它像心跳一樣每隔固定時間發(fā)一次,以此來告訴服務器,這個客戶端還活著。事實上這是為了保持長連接,至于這個包的內容,是沒有什么特別規(guī)定的,不過一般都是很小的包,或者只包含包頭的一個空包。
???在TCP的機制里面,本身是存在有心跳包的機制的,也就是TCP的選項:SO_KEEPALIVE。系統(tǒng)默認是設置的2小時的心跳頻率。但是它檢查不到機器斷電、網線拔出、防火墻這些斷線。而且邏輯層處理斷線可能也不是那么好處理。一般,如果只是用于保活還是可以的。
???心跳包一般來說都是在邏輯層發(fā)送空的echo包來實現(xiàn)的。下一個定時器,在一定時間間隔下發(fā)送一個空包給客戶端,然后客戶端反饋一個同樣的空包回來,服務器如果在一定時間內收不到客戶端發(fā)送過來的反饋包,那就只有認定說掉線了。
???其實,要判定掉線,只需要send或者recv一下,如果結果為零,則為掉線。但是,在長連接下,有可能很長一段時間都沒有數(shù)據往來。理論上說,這個連接是一直保持連接的,但是實際情況中,如果中間節(jié)點出現(xiàn)什么故障是難以知道的。更要命的是,有的節(jié)點(防火墻)會自動把一定時間之內沒有數(shù)據交互的連接給斷掉。在這個時候,就需要我們的心跳包了,用于維持長連接,保活。
???在獲知了斷線之后,服務器邏輯可能需要做一些事情,比如斷線后的數(shù)據清理呀,重新連接呀……當然,這個自然是要由邏輯層根據需求去做了。
???總的來說,心跳包主要也就是用于長連接的保活和斷線處理。一般的應用下,判定時間在30-40秒比較不錯。如果實在要求高,那就在6-9秒。
心跳檢測步驟:
1客戶端每隔一個時間間隔發(fā)生一個探測包給服務器
2客戶端發(fā)包時啟動一個超時定時器
3服務器端接收到檢測包,應該回應一個包
4如果客戶機收到服務器的應答包,則說明服務器正常,刪除超時定時器
5如果客戶端的超時定時器超時,依然沒有收到應答包,則說明服務器掛了
轉自:http://blog.sina.com.cn/s/blog_a459dcf5010153m5.html
根據上面的介紹我們可以知道對端以一種非優(yōu)雅的方式斷開連接的時候,我們可以設置SO_KEEPALIVE屬性使得我們在2小時以后發(fā)現(xiàn)對方的TCP連接是否依然存在。
具體操作:
??? //設置KeepAlive??? ?
?? 1、 BOOL?? bKeepAlive?? =?? TRUE;??? ?
?? ?int nRet=::setsockopt(sockClient,SOL_SOCKET,SO_KEEPALIVE,(char*)&bKeepAlive,sizeof(bKeepAlive));??? ?
?? ?if(nRet!=0)?? ?
?? ?{??? ?
?? ?????AfxMessageBox("出錯");
?? ??? ?return?? ;
?? ?}??? ?
?? ?
?? 2、感覺兩小時時間太長可以自行設定方法1
//設置KeepAlive檢測時間和次數(shù)??? ?
?? ?tcp_keepalive??? inKeepAlive?? =?? {0};?? //輸入參數(shù)??? ?
?? ?unsigned?? long?? ulInLen?? =?? sizeof(tcp_keepalive );??????? ?
?? ?
?? ?tcp_keepalive??? outKeepAlive?? =?? {0};?? //輸出參數(shù)??? ?
?? ?unsigned?? long?? ulOutLen?? =?? sizeof(tcp_keepalive );??????? ?
?? ?
?? ?unsigned?? long?? ulBytesReturn?? =?? 0;??? ?
?? ?
?? ?//設置socket的keep?? alive為10秒,并且發(fā)送次數(shù)為3次??? ?
?? ?inKeepAlive.onoff?? =?? 1;????? ?
?? ?inKeepAlive.keepaliveinterval?? =?? 4000;?? //兩次KeepAlive探測間的時間間隔??? ?
?? ?inKeepAlive.keepalivetime?? =?? 1000;?? //開始首次KeepAlive探測前的TCP空閉時間??? ?
?? ?
?? ?nRet=WSAIoctl(sockClient,????? ?
?? ??? ?SIO_KEEPALIVE_VALS,??? ?
?? ??? ?(LPVOID)&inKeepAlive,??? ?
?? ??? ?ulInLen,??? ?
?? ??? ?(LPVOID)&outKeepAlive,??? ?
?? ??? ?ulOutLen,??? ?
?? ??? ?&ulBytesReturn,??? ?
?? ??? ?NULL,??? ?
?? ??? ?NULL);??? ?
?? ?if(SOCKET_ERROR?? ==?? nRet)??? ?
?? ?{??? ?
?? ??? ?AfxMessageBox("出錯");
?? ??? ?return;?? ?
?? ?}??
3、感覺兩小時時間太長可以自行設定方法2
因此我們可以得到
? ? int? ?? ?? ?? ?? ???keepIdle = 6;
? ? int? ?? ?? ?? ?? ???keepInterval = 5;
? ? int? ?? ?? ?? ?? ???keepCount = 3;
? ? Setsockopt(listenfd, SOL_TCP, TCP_KEEPIDLE, (void *)&keepIdle, sizeof(keepIdle));
? ? Setsockopt(listenfd, SOL_TCP,TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));
? ? Setsockopt(listenfd,SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));
詳見:http://blog.csdn.net/gavin1203/article/details/5290609
對setsockopt的操作,詳見:http://www.cnblogs.com/hateislove214/archive/2010/11/05/1869886.html
總結
以上是生活随笔為你收集整理的Socket心跳包机制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: socket心跳检测
- 下一篇: 面试必备之:MFC socket编程(浅