Socket心跳包機(jī)制

<轉(zhuǎn)自CSDN技術(shù)博客>
心跳包的發(fā)送绷跑,通常有兩種技術(shù)
方法1:應(yīng)用層自己實(shí)現(xiàn)的心跳包
由應(yīng)用程序自己發(fā)送心跳包來檢測(cè)連接是否正常,大致的方法是:服務(wù)器在一個(gè) Timer事件中定時(shí) 向客戶端發(fā)送一個(gè)短小精悍的數(shù)據(jù)包凡资,然后啟動(dòng)一個(gè)低級(jí)別的線程砸捏,在該線程中不斷檢測(cè)客戶端的回應(yīng), 如果在一定時(shí)間內(nèi)沒有收到客戶端的回應(yīng)隙赁,即認(rèn)為客戶端已經(jīng)掉線带膜;同樣,如果客戶端在一定時(shí)間內(nèi)沒 有收到服務(wù)器的心跳包鸳谜,則認(rèn)為連接不可用。

方法2:TCP的KeepAlive备琅ぃ活機(jī)制
因?yàn)橐紤]到一個(gè)服務(wù)器通常會(huì)連接多個(gè)客戶端芭挽,因此由用戶在應(yīng)用層自己實(shí)現(xiàn)心跳包,代碼較多 且稍顯復(fù)雜蝗肪,而利用TCP/IP協(xié)議層為內(nèi)置的KeepAlive功能來實(shí)現(xiàn)心跳功能則簡(jiǎn)單得多袜爪。 不論是服務(wù)端還是客戶端,一方開啟KeepAlive功能后薛闪,就會(huì)自動(dòng)在規(guī)定時(shí)間內(nèi)向?qū)Ψ桨l(fā)送心跳包辛馆, 而另一方在收到心跳包后就會(huì)自動(dòng)回復(fù),以告訴對(duì)方我仍然在線豁延。 因?yàn)殚_啟KeepAlive功能需要消耗額外的寬帶和流量昙篙,所以TCP協(xié)議層默認(rèn)并不開啟KeepAlive功 能,盡管這微不足道诱咏,但在按流量計(jì)費(fèi)的環(huán)境下增加了費(fèi)用苔可,另一方面,KeepAlive設(shè)置不合理時(shí)可能會(huì) 因?yàn)槎虝旱木W(wǎng)絡(luò)波動(dòng)而斷開健康的TCP連接袋狞。并且焚辅,默認(rèn)的KeepAlive超時(shí)需要7,200,000 MilliSeconds苟鸯, 即2小時(shí)同蜻,探測(cè)次數(shù)為5次。對(duì)于很多服務(wù)端應(yīng)用程序來說早处,2小時(shí)的空閑時(shí)間太長(zhǎng)湾蔓。因此,我們需要手工開啟KeepAlive功能并設(shè)置合理的KeepAlive參數(shù)陕赃。
以上轉(zhuǎn)自網(wǎng)絡(luò)卵蛉。

心跳包機(jī)制
跳包之所以叫心跳包是因?yàn)椋核裥奶粯用扛艄潭〞r(shí)間發(fā)一次,以此來告訴服務(wù)器么库,這個(gè)客戶端還活著傻丝。事實(shí)上這是為了保持長(zhǎng)連接,至于這個(gè)包的內(nèi)容诉儒,是沒有什么特別規(guī)定的葡缰,不過一般都是很小的包,或者只包含包頭的一個(gè)空包忱反。 在TCP的機(jī)制里面泛释,本身是存在有心跳包的機(jī)制的,也就是TCP的選項(xiàng):SO_KEEPALIVE温算。系統(tǒng)默認(rèn)是設(shè)置的2小時(shí)的心跳頻率怜校。但是它檢查不到機(jī)器斷電、網(wǎng)線拔出注竿、防火墻這些斷線茄茁。而且邏輯層處理斷線可能也不是那么好處理。一般巩割,如果只是用于比雇纾活還是可以的。 心跳包一般來說都是在邏輯層發(fā)送空的echo包來實(shí)現(xiàn)的宣谈。下一個(gè)定時(shí)器愈犹,在一定時(shí)間間隔下發(fā)送一個(gè)空包給客戶端,然后客戶端反饋一個(gè)同樣的空包回來闻丑,服務(wù)器如果在一定時(shí)間內(nèi)收不到客戶端發(fā)送過來的反饋包漩怎,那就只有認(rèn)定說掉線了。 其實(shí)嗦嗡,要判定掉線扬卷,只需要send或者recv一下,如果結(jié)果為零酸钦,則為掉線怪得。但是,在長(zhǎng)連接下卑硫,有可能很長(zhǎng)一段時(shí)間都沒有數(shù)據(jù)往來徒恋。理論上說,這個(gè)連接是一直保持連接的欢伏,但是實(shí)際情況中入挣,如果中間節(jié)點(diǎn)出現(xiàn)什么故障是難以知道的。更要命的是硝拧,有的節(jié)點(diǎn)(防火墻)會(huì)自動(dòng)把一定時(shí)間之內(nèi)沒有數(shù)據(jù)交互的連接給斷掉径筏。在這個(gè)時(shí)候葛假,就需要我們的心跳包了,用于維持長(zhǎng)連接滋恬,绷难担活。 在獲知了斷線之后恢氯,服務(wù)器邏輯可能需要做一些事情带斑,比如斷線后的數(shù)據(jù)清理呀,重新連接呀……當(dāng)然勋拟,這個(gè)自然是要由邏輯層根據(jù)需求去做了勋磕。 總的來說,心跳包主要也就是用于長(zhǎng)連接的备颐遥活和斷線處理挂滓。一般的應(yīng)用下,判定時(shí)間在30-40秒比較不錯(cuò)啸胧。如果實(shí)在要求高杂彭,那就在6-9秒。

心跳檢測(cè)步驟:1客戶端每隔一個(gè)時(shí)間間隔發(fā)生一個(gè)探測(cè)包給服務(wù)器2客戶端發(fā)包時(shí)啟動(dòng)一個(gè)超時(shí)定時(shí)器3服務(wù)器端接收到檢測(cè)包吓揪,應(yīng)該回應(yīng)一個(gè)包4如果客戶機(jī)收到服務(wù)器的應(yīng)答包亲怠,則說明服務(wù)器正常,刪除超時(shí)定時(shí)器5如果客戶端的超時(shí)定時(shí)器超時(shí)柠辞,依然沒有收到應(yīng)答包团秽,則說明服務(wù)器掛了轉(zhuǎn)自:http://blog.sina.com.cn/s/blog_a459dcf5010153m5.html
根據(jù)上面的介紹我們可以知道對(duì)端以一種非優(yōu)雅的方式斷開連接的時(shí)候,我們可以設(shè)置SO_KEEPALIVE屬性使得我們?cè)?小時(shí)以后發(fā)現(xiàn)對(duì)方的TCP連接是否依然存在叭首。具體操作:
//設(shè)置KeepAlive
1习勤、

BOOL   bKeepAlive   =   TRUE;       
  int nRet=::
setsockopt(sockClient,SOL_SOCKET,SO_KEEPALIVE,(char*)&bKeepAlive,sizeof(bKeepAlive));  
       if(nRet!=0)        {            
 AfxMessageBox("出錯(cuò)");  
       return   ;   
 }            
2、感覺兩小時(shí)時(shí)間太長(zhǎng)可以自行設(shè)定方法1 //設(shè)置KeepAlive檢測(cè)時(shí)間和次數(shù)       
  tcp_keepalive    inKeepAlive   =   {0};   //輸入?yún)?shù)        
 unsigned   long   ulInLen   =   sizeof(tcp_keepalive );             
    tcp_keepalive    outKeepAlive   =   {0};   //輸出參數(shù)        
 unsigned   long   ulOutLen   =   sizeof(tcp_keepalive );              
   unsigned   long   ulBytesReturn   =   0;            
 //設(shè)置socket的keep   alive為10秒焙格,并且發(fā)送次數(shù)為3次        
 inKeepAlive.onoff   =   1;           
inKeepAlive.keepaliveinterval   =   4000;  
 //兩次KeepAlive探測(cè)間的時(shí)間間隔         
inKeepAlive.keepalivetime   =   1000;   
//開始首次KeepAlive探測(cè)前的TCP空閉時(shí)間             
nRet=WSAIoctl(sockClient,               
SIO_KEEPALIVE_VALS,             
(LPVOID)&inKeepAlive,             
ulInLen,             
(LPVOID)&outKeepAlive,             
ulOutLen,     &ulBytesReturn,        NULL,             NULL);       
 if(SOCKET_ERROR   ==   nRet)         {          
   AfxMessageBox("出錯(cuò)");      
  return;      
  }  
 3图毕、感覺兩小時(shí)時(shí)間太長(zhǎng)可以自行設(shè)定方法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對(duì)setsockopt的操作,
詳見:http://www.cnblogs.com/hateislove214/archive/2010/11/05/1869886.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末眷唉,一起剝皮案震驚了整個(gè)濱河市予颤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌冬阳,老刑警劉巖蛤虐,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異肝陪,居然都是意外死亡驳庭,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來饲常,“玉大人蹲堂,你說我怎么就攤上這事”从伲” “怎么了柒竞?”我有些...
    開封第一講書人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)霹娄。 經(jīng)常有香客問我,道長(zhǎng)鲫骗,這世上最難降的妖魔是什么犬耻? 我笑而不...
    開封第一講書人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮执泰,結(jié)果婚禮上枕磁,老公的妹妹穿的比我還像新娘。我一直安慰自己术吝,他們只是感情好计济,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著排苍,像睡著了一般沦寂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上淘衙,一...
    開封第一講書人閱讀 51,541評(píng)論 1 305
  • 那天传藏,我揣著相機(jī)與錄音,去河邊找鬼彤守。 笑死毯侦,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的具垫。 我是一名探鬼主播侈离,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼筝蚕!你這毒婦竟也來了卦碾?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤起宽,失蹤者是張志新(化名)和其女友劉穎蔗坯,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體燎含,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宾濒,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了屏箍。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绘梦。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡橘忱,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出卸奉,到底是詐尸還是另有隱情钝诚,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布榄棵,位于F島的核電站凝颇,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏疹鳄。R本人自食惡果不足惜拧略,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望瘪弓。 院中可真熱鬧垫蛆,春花似錦、人聲如沸腺怯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽呛占。三九已至虑乖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間晾虑,已是汗流浹背决左。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留走贪,地道東北人佛猛。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像坠狡,于是被迫代替她去往敵國(guó)和親继找。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Tcp的斷線檢測(cè) tcp的斷線檢測(cè)逃沿,分為兩種: ① 利用tcp自帶的keep –alive機(jī)制 ② ...
    程序員學(xué)園閱讀 7,601評(píng)論 1 2
  • 1婴渡、TCP狀態(tài)linux查看tcp的狀態(tài)命令:1)、netstat -nat 查看TCP各個(gè)狀態(tài)的數(shù)量2)凯亮、lso...
    北辰青閱讀 9,423評(píng)論 0 11
  • UDP:用戶數(shù)據(jù)報(bào)協(xié)議:主要用在實(shí)時(shí)性要求比較高的以及對(duì)質(zhì)量相對(duì)較弱的地方.但是面對(duì)現(xiàn)在高質(zhì)量的線路不會(huì)容易丟包,...
    CoderZS閱讀 7,320評(píng)論 0 24
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理边臼,服務(wù)發(fā)現(xiàn),斷路器假消,智...
    卡卡羅2017閱讀 134,657評(píng)論 18 139
  • Socket心跳包機(jī)制
    davidxiyu閱讀 1,058評(píng)論 0 1