Socket心跳包機制

<轉自CSDN技術博客>
心跳包的發送,通常有兩種技術
方法1:應用層自己實現的心跳包
由應用程序自己發送心跳包來檢測連接是否正常,大致的方法是:服務器在一個 Timer事件中定時 向客戶端發送一個短小精悍的數據包,然后啟動一個低級別的線程,在該線程中不斷檢測客戶端的回應, 如果在一定時間內沒有收到客戶端的回應,即認為客戶端已經掉線;同樣,如果客戶端在一定時間內沒 有收到服務器的心跳包,則認為連接不可用。

方法2:TCP的KeepAlive保活機制
因為要考慮到一個服務器通常會連接多個客戶端,因此由用戶在應用層自己實現心跳包,代碼較多 且稍顯復雜,而利用TCP/IP協議層為內置的KeepAlive功能來實現心跳功能則簡單得多。 不論是服務端還是客戶端,一方開啟KeepAlive功能后,就會自動在規定時間內向對方發送心跳包, 而另一方在收到心跳包后就會自動回復,以告訴對方我仍然在線。 因為開啟KeepAlive功能需要消耗額外的寬帶和流量,所以TCP協議層默認并不開啟KeepAlive功 能,盡管這微不足道,但在按流量計費的環境下增加了費用,另一方面,KeepAlive設置不合理時可能會 因為短暫的網絡波動而斷開健康的TCP連接。并且,默認的KeepAlive超時需要7,200,000 MilliSeconds, 即2小時,探測次數為5次。對于很多服務端應用程序來說,2小時的空閑時間太長。因此,我們需要手工開啟KeepAlive功能并設置合理的KeepAlive參數。
以上轉自網絡。

心跳包機制
跳包之所以叫心跳包是因為:它像心跳一樣每隔固定時間發一次,以此來告訴服務器,這個客戶端還活著。事實上這是為了保持長連接,至于這個包的內容,是沒有什么特別規定的,不過一般都是很小的包,或者只包含包頭的一個空包。 在TCP的機制里面,本身是存在有心跳包的機制的,也就是TCP的選項:SO_KEEPALIVE。系統默認是設置的2小時的心跳頻率。但是它檢查不到機器斷電、網線拔出、防火墻這些斷線。而且邏輯層處理斷線可能也不是那么好處理。一般,如果只是用于保活還是可以的。 心跳包一般來說都是在邏輯層發送空的echo包來實現的。下一個定時器,在一定時間間隔下發送一個空包給客戶端,然后客戶端反饋一個同樣的空包回來,服務器如果在一定時間內收不到客戶端發送過來的反饋包,那就只有認定說掉線了。 其實,要判定掉線,只需要send或者recv一下,如果結果為零,則為掉線。但是,在長連接下,有可能很長一段時間都沒有數據往來。理論上說,這個連接是一直保持連接的,但是實際情況中,如果中間節點出現什么故障是難以知道的。更要命的是,有的節點(防火墻)會自動把一定時間之內沒有數據交互的連接給斷掉。在這個時候,就需要我們的心跳包了,用于維持長連接,保活。 在獲知了斷線之后,服務器邏輯可能需要做一些事情,比如斷線后的數據清理呀,重新連接呀……當然,這個自然是要由邏輯層根據需求去做了。 總的來說,心跳包主要也就是用于長連接的保活和斷線處理。一般的應用下,判定時間在30-40秒比較不錯。如果實在要求高,那就在6-9秒。

心跳檢測步驟:1客戶端每隔一個時間間隔發生一個探測包給服務器2客戶端發包時啟動一個超時定時器3服務器端接收到檢測包,應該回應一個包4如果客戶機收到服務器的應答包,則說明服務器正常,刪除超時定時器5如果客戶端的超時定時器超時,依然沒有收到應答包,則說明服務器掛了轉自:http://blog.sina.com.cn/s/blog_a459dcf5010153m5.html
根據上面的介紹我們可以知道對端以一種非優雅的方式斷開連接的時候,我們可以設置SO_KEEPALIVE屬性使得我們在2小時以后發現對方的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檢測時間和次數       
  tcp_keepalive    inKeepAlive   =   {0};   //輸入參數        
 unsigned   long   ulInLen   =   sizeof(tcp_keepalive );             
    tcp_keepalive    outKeepAlive   =   {0};   //輸出參數        
 unsigned   long   ulOutLen   =   sizeof(tcp_keepalive );              
   unsigned   long   ulBytesReturn   =   0;            
 //設置socket的keep   alive為10秒,并且發送次數為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/5290609setsockopt的操作,
詳見:http://www.cnblogs.com/hateislove214/archive/2010/11/05/1869886.html

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,237評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,957評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,248評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,356評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,081評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,485評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,534評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,720評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,263評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,025評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,204評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,787評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,461評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,874評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,105評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,945評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,205評論 2 375

推薦閱讀更多精彩內容