日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國(guó)內(nèi)最全I(xiàn)T社區(qū)平臺(tái) 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁(yè) > 互聯(lián)網(wǎng) > 如何在socket編程的Tcp連接中實(shí)現(xiàn)心跳協(xié)議

如何在socket編程的Tcp連接中實(shí)現(xiàn)心跳協(xié)議

來(lái)源:程序員人生   發(fā)布時(shí)間:2014-10-10 08:00:00 閱讀次數(shù):2141次
心跳包的發(fā)送,通常有兩種技術(shù)
方法1:應(yīng)用層自己實(shí)現(xiàn)的心跳包 

由應(yīng)用程序自己發(fā)送心跳包來(lái)檢測(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功能來(lái)實(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)用程序來(lái)說(shuō),2小時(shí)的空閑時(shí)間太長(zhǎng)。因此,我們需要手工開啟KeepAlive功能并設(shè)置合理的KeepAlive參數(shù)。
以上轉(zhuǎn)自網(wǎng)絡(luò)。



心跳包機(jī)制
  跳包之所以叫心跳包是因?yàn)椋核裥奶粯用扛艄潭〞r(shí)間發(fā)一次,以此來(lái)告訴服務(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)線拔出、防火墻這些斷線。而且邏輯層處理斷線可能也不是那么好處理。一般,如果只是用于保活還是可以的。
   心跳包一般來(lái)說(shuō)都是在邏輯層發(fā)送空的echo包來(lái)實(shí)現(xiàn)的。下一個(gè)定時(shí)器,在一定時(shí)間間隔下發(fā)送一個(gè)空包給客戶端,然后客戶端反饋一個(gè)同樣的空包回來(lái),服務(wù)器如果在一定時(shí)間內(nèi)收不到客戶端發(fā)送過來(lái)的反饋包,那就只有認(rèn)定說(shuō)掉線了。
   其實(shí),要判定掉線,只需要send或者recv一下,如果結(jié)果為零,則為掉線。但是,在長(zhǎng)連接下,有可能很長(zhǎng)一段時(shí)間都沒有數(shù)據(jù)往來(lái)。理論上說(shuō),這個(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ù)需求去做了。
   總的來(lái)說(shuō),心跳包主要也就是用于長(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)答包,則說(shuō)明服務(wù)器正常,刪除超時(shí)定時(shí)器
5如果客戶端的超時(shí)定時(shí)器超時(shí),依然沒有收到應(yīng)答包,則說(shuō)明服務(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
生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 亚洲电影中文字幕 | 国产精品一区在线观看 | 欧美日韩一区二区三区视频 | 国产成人精品一区二区三区 | 91精品一区二区三区久久久久久 | 国产a区| 亚洲精品福利视频 | 九九av| 免费a级毛片大学生免费观看 | 亚洲欧美在线一区 | 亚洲一区二区三区免费在线观看 | 国产欧美日韩综合 | 午夜日韩 | 五月婷婷综合网 | 久草热在线 | 亚洲国产精品久久久 | 欧美成人精品一区二区三区 | 国产一区二区三区四区大秀 | 欧美一区二区三区久久精品 | 天天干夜夜草 | 中文字幕日产av一二三区 | 久热这里只有精品6 | 一区二区三区在线播放 | 中文日韩 | 亚洲黄色免费电影 | 久久精品视频网站 | 免费成人高清 | 国产精品久久久久国产a级 中文字幕影院 | 国产黄色在线网站 | 婷久久 | 欧美视频区 | 日韩激情在线 | 久久久亚洲成人 | 最新黄色在线视频 | 香蕉视频成年人 | 青青草一区 | 日韩精品一区二区三区电影在线看 | 国精品一区 | 日本一二三区视频 | 色综合91 | 日日干天天射 |