<output id="r87xx"></output>
    1. 
      
      <mark id="r87xx"><thead id="r87xx"><input id="r87xx"></input></thead></mark>
        •   

               當(dāng)前位置:首頁(yè)>管理咨詢>TCP通信中服務(wù)器處理客戶端意外斷開的處理 查詢:
               
          TCP通信中服務(wù)器處理客戶端意外斷開的處理

                  如果TCP連接被對(duì)方正常關(guān)閉,也就是說,對(duì)方是正確地調(diào)用了closesocket(s)或者shutdown(s)的話,那么上面的Recv或Send調(diào)用就能馬上返回,并且報(bào)錯(cuò)。這是由于close  socket(s)或者shutdown(s)有個(gè)正常的關(guān)閉過程,會(huì)告訴對(duì)方TCP連接已經(jīng)關(guān)閉,你不需要再發(fā)送或者接受消息了。

                  但是,如果意外斷開,客戶端(3g的移動(dòng)設(shè)備)并沒有正常關(guān)閉socket。雙方并未按照協(xié)議上的四次揮手去斷開連接。

                  那么這時(shí)候正在執(zhí)行Recv或Send操作的一方就會(huì)因?yàn)闆]有任何連接中斷的通知而一直等待下去,也就是會(huì)被長(zhǎng)時(shí)間卡住。

                  像這種如果一方已經(jīng)關(guān)閉或異常終止連接,而另一方卻不知道,我們將這樣的TCP連接稱為半打 的。

                  解決意外中斷辦法都是利用保活機(jī)制。而?;顧C(jī)制分又可以讓底層實(shí)現(xiàn)也可自己實(shí)現(xiàn)。

                  1、 自己編寫心跳包程序

                  簡(jiǎn)單的說也就是在自己的程序中加入一條線程,定時(shí)向?qū)Χ税l(fā)送數(shù)據(jù)包,查看是否有ACK,如果有則連接正常,沒有的話則連接斷開

                  2、 啟動(dòng)TCP編程里的keepAlive機(jī)制

                  一)雙方擬定心跳(自實(shí)現(xiàn))

                  一般由客戶端發(fā)送心跳包,服務(wù)端并不回應(yīng)心跳,只是定時(shí)輪詢判斷一下與上次的時(shí)間間隔是否超時(shí)(超時(shí)時(shí)間自己設(shè)定)。服務(wù)器并不主動(dòng)發(fā)送是不想增添服務(wù)器的通信量,減少壓力。

                  但這會(huì)出現(xiàn)三種情況:

                  情況1.

                  客戶端由于某種網(wǎng)絡(luò)延遲等原因很久后才發(fā)送心跳(它并沒有斷),這時(shí)服務(wù)器若利用自身設(shè)定的超時(shí)判斷其已經(jīng)斷開,而后去關(guān)閉socket。若客戶端有重連機(jī)制,則客戶端會(huì)重新連接。若不確定這種方式是否關(guān)閉了原本正常的客戶端,則在ShutDown的時(shí)候一定要選擇send,表示關(guān)閉發(fā)送通道,服務(wù)器還可以接收一下,萬一客戶端正在發(fā)送比較重要的數(shù)據(jù)呢,是不?

                  情況2.

                  客戶端很久沒傳心跳,確實(shí)是自身斷掉了。在其重啟之前,服務(wù)端已經(jīng)判斷出其超時(shí),并主動(dòng)close,則四次揮手成功交互。

                  情況3.

                  客戶端很久沒傳心跳,確實(shí)是自身斷掉了。在其重啟之前,服務(wù)端的輪詢還未判斷出其超時(shí),在未主動(dòng)close的時(shí)候該客戶端已經(jīng)重新連接。

                  這時(shí)候若客戶端斷開的時(shí)候發(fā)送了FIN包,則服務(wù)端將會(huì)處于CLOSE_WA上網(wǎng)行為狀態(tài);

                  這時(shí)候若客戶端斷開的時(shí)候未發(fā)送FIN包,則服務(wù)端處還是顯示ESTABLISHED狀態(tài);

                  而新連接上來的客戶端(也就是剛才斷掉的重新連上來了)在服務(wù)端肯定是ESTABLISHED;這時(shí)候就有個(gè)問題,若利用輪詢還未檢測(cè)出上條舊連接已經(jīng)超時(shí)(這很正常,timer總有個(gè)間隔吧),而在這時(shí),客戶端又重復(fù)的上演情況3,那么服務(wù)端將會(huì)出現(xiàn)大量的假的ESTABLISHED連接和CLOSE_WA上網(wǎng)行為連接。

                  最終結(jié)果就是新的其他客戶端無法連接上來,但是利用netstat還是能看到一條連接已經(jīng)建立,并顯示ESTABLISHED,但始終無法進(jìn)入程序代碼。個(gè)人最初感覺導(dǎo)致這種情況是因?yàn)榧俚腅STABLISHED連接和  CLOSE_WA上網(wǎng)行為連接會(huì)占用較大的系統(tǒng)資源,程序無法再次創(chuàng)建連接(因?yàn)槊看挝野l(fā)現(xiàn)這個(gè)問題的時(shí)候我只連了10個(gè)左右客戶端卻已經(jīng)有40多條無效連接)。而最近幾天測(cè)試卻發(fā)現(xiàn)有一次程序內(nèi)只連接了2,3個(gè)設(shè)備,但是有8條左右的虛連接,此時(shí)已經(jīng)連接不了新客戶端了。這時(shí)候我就覺得我想錯(cuò)了,不可能這幾條連接就占用了大量連接把,如果說幾十條還有可能。但是能肯定的是,這個(gè)問題的產(chǎn)生絕對(duì)是設(shè)備在不停的重啟,而服務(wù)器這邊又是簡(jiǎn)單的輪詢,并不能及時(shí)處理,暫時(shí)還未能解決。

                  二)利用KeepAlive

                  其實(shí)keepalive的原理就是TCP內(nèi)嵌的一個(gè)心跳包,

                  以服務(wù)器端為例,如果當(dāng)前 server 端檢測(cè)到超過一定時(shí)間(默認(rèn)是 7,200,000 milliseconds ,也就是 2  個(gè)小時(shí))沒有數(shù)據(jù)傳輸,那么會(huì)向 client 端發(fā)送一個(gè) keep-alive packet (該 keep-alive packet 就是 ACK和 當(dāng)前  TCP 序列號(hào)減一的組合),此時(shí) client 端應(yīng)該為以下三種情況之一:

                  1. client 端仍然存在,網(wǎng)絡(luò)連接狀況良好。此時(shí) client 端會(huì)返回一個(gè) ACK 。server 端接收到  ACK 后重置計(jì)時(shí)器(復(fù)位存活定時(shí)器),在 2 小時(shí)后再發(fā)送探測(cè)。如果 2 小時(shí)內(nèi)連接上有數(shù)據(jù)傳輸,那么在該時(shí)間基礎(chǔ)上向后推延 2 個(gè)小時(shí)。

                  2. 客戶端異常關(guān)閉,或是網(wǎng)絡(luò)斷開。在這兩種情況下, client  端都不會(huì)響應(yīng)。服務(wù)器沒有收到對(duì)其發(fā)出探測(cè)的響應(yīng),并且在一定時(shí)間(系統(tǒng)默認(rèn)為 1000 ms )后重復(fù)發(fā)送 keep-alive packet  ,并且重復(fù)發(fā)送一定次數(shù)( 2000 XP 2003 系統(tǒng)默認(rèn)為 5 次 , Vista 后的系統(tǒng)默認(rèn)為 10 次)。

                  3.  客戶端曾經(jīng)崩潰,但已經(jīng)重啟。這種情況下,服務(wù)器將會(huì)收到對(duì)其存活探測(cè)的響應(yīng),但該響應(yīng)是一個(gè)復(fù)位,從而引起服務(wù)器對(duì)連接的終止。

                  對(duì)于應(yīng)用程序來說,2小時(shí)的空閑時(shí)間太長(zhǎng)。因此,我們需要手工開啟Keepalive功能并設(shè)置合理的Keepalive參數(shù)。

                  全局設(shè)置可更改 /etc/sysctl.conf ,加上:

                  net.ipv4.tcp_keepalive_intvl = 20

                  net.ipv4.tcp_keepalive_probes = 3

                  net.ipv4.tcp_keepalive_time = 60

                  在程序中設(shè)置如下:

                  
                  #include sys/socket.h  
           #include netinet/in.h  
           #include arpa/inet.h  
           #include sys/types.h  
           #include netinet/tcp.h  
            
           int keepAlive = 1; // 開啟keepalive屬性  
           int keepIdle = 60; // 如該連接在60秒內(nèi)沒有任何數(shù)據(jù)往來,則進(jìn)行探測(cè)   
           int keepInterval = 5; // 探測(cè)時(shí)發(fā)包的時(shí)間間隔為5 秒  
           int keepCount = 3; // 探測(cè)嘗試的次數(shù).如果第1次探測(cè)包就收到響應(yīng)了,則后2次的不再發(fā).  
            
           setsockopt(rs, SOL_SOCKET, SO_KEEPALIVE, (void *)keepAlive, sizeof(keepAlive));  
           setsockopt(rs, SOL_TCP, TCP_KEEPIDLE, (void*)keepIdle, sizeof(keepIdle));  
           setsockopt(rs, SOL_TCP, TCP_KEEPINTVL, (void *)keepInterval, sizeof(keepInterval));  
           setsockopt(rs, SOL_TCP, TCP_KEEPCNT, (void *)keepCount, sizeof(keepCount));

                  在程序中表現(xiàn)為,當(dāng)tcp檢測(cè)到對(duì)端socket不再可用時(shí)(不能發(fā)出探測(cè)包,或探測(cè)包沒有收到ACK的響應(yīng)包),select會(huì)返回socket可讀,并且在recv時(shí)返回-1,同時(shí)置上errno為ETIMEDOUT.

               


          網(wǎng)絡(luò)分段的優(yōu)缺點(diǎn)及最佳做法三層交換機(jī)的主要種類及應(yīng)用
          確立企業(yè)的招聘原則民營(yíng)企業(yè)的人力資源管理誤區(qū)
          網(wǎng)絡(luò)管理基本知識(shí):TCP的四種定時(shí)器網(wǎng)管員必知:常用電腦密碼破解
          職場(chǎng)新手如何快速成長(zhǎng)?謹(jǐn)記這9招!如何設(shè)計(jì)人力資源管理體系?
          移動(dòng)互聯(lián)網(wǎng)企業(yè)IT性能管理實(shí)踐ERP項(xiàng)目實(shí)施的經(jīng)驗(yàn)教訓(xùn)
          大數(shù)據(jù)中心日常維護(hù)工作總結(jié)網(wǎng)管須知:Wi-Fi的十大誤解
          網(wǎng)絡(luò)分段的優(yōu)缺點(diǎn)及挑戰(zhàn)IT運(yùn)維管理的規(guī)劃與決策分析如何進(jìn)行?
          信息發(fā)布:廣州名易軟件有限公司 http://www.jetlc.com
          • 勁爆價(jià):
            不限功能
            不限用戶
            1998元/年

          • 微信客服

            <output id="r87xx"></output>
          1. 
            
            <mark id="r87xx"><thead id="r87xx"><input id="r87xx"></input></thead></mark>
              • 日本色管视频 | 天堂在线资源视频 | 国产草视频在线播放 | 亚洲黄色在线视频观看 | 日韩婬乱片A片AAA真人视频 | 爱操逼综合网 | 精品国产91久久久久久暴行片 | 亚洲v天堂 | 午夜九九| 另类罕见稀奇videos |