TCP/IP 筆記 - TCP保活機制


TCP協議中不存在輪詢機制,這意味着加入啟動一個客戶端進程,與服務器建立連接后,然后離開幾小時、幾天、甚至幾個月,連接依然會保持着。理論上,中間路由器可以崩潰和重啟,數據線可以斷開再連接,只要連接兩端的主機沒有被重新啟動(或者更改IP地址),那么它們仍會保持連接狀態。

TCP保活機制

TCP保活機制是一種在不影響數據流內容的情況下探測對方的方式。它由一個保活計時器實現,當計時器被激發,連接一端將發送一個保活探測(簡稱保活)報文,另一端接收報文的同時會發送一個ACK作為響應。

保活機制並不是TCP規范中的一部分,對此[RFC1122]給出三個理由:

  1. 在出現短暫的網絡錯誤的時候,保活機制會使一個好的連接斷開

  2. 保活機制會占用不必要的帶寬

  3. 在按流量計費的情況下會產生更多經濟開銷

並且保活機制仍存在爭議,許多人認為這一功能不應該在TCP協議中提供,而應在應用程序中實現;反之也有人認為大多數應用程序需要該功能,應該在TCP協議中實現。然后...現在所有主流TCP版本都實現了保活功能,只是該功能在默認情況下是關閉的,是一個可選擇激活的功能。

TCP連接的任何一端都可以請求打開這一功能,且可以設置在連接的一端、兩端或者兩端都沒有。

保活功能的操作如下:如果在一段時間(保活時間)內連接處於非活動狀態,開啟保活功能的一端將向對方發送一個保活探測報文。如果發送端沒有收到響應報文,那么經過一個已經提前配置好的保活時間間隔后繼續發送一個保活探測報文,直到發送探測報文的次數達到保活探測數,這時對方主機將被確認為不可到達,連接也將被中斷。

TCP保活功能的規則過程中,開啟該功能的一端會發現對方處於以下四種狀態之一:

  1. 對方主機仍在工作,並且可以到達。請求端將保活計時器重置(重新設定為保活時間值)。如果在計時器超時前有應用程序通過該連接傳輸數據,那么計時器將再次被設定為保活時間值。

  2. 對方主機已經奔潰,包括已經關閉或者正在重新啟動。請求端接收不到響應報文,並在經過保活時間間隔指定的時間后超時。超時前,請求端會持續發送探測報文,一共發送保活探測數指定次數為止,如果請求端沒收到任何探測報文響應,那么它將認為對方主機已經關閉,連接也將被斷開。

  3. 客戶主機奔潰並且已重啟。請求端會受到一個對其保活探測報文的響應,但這個響應是一個重置報文段,請求端將會斷開連接。

  4. 對方主機仍在工作,但是由於某些原因不能到達請求端。這種情況與狀態2相同,因為TCP不能區分狀態2和狀態4,結果都是沒有受到探測報文的響應。

變量保活時間、保活時間間隔和保活探測數的設置是可以變更的。有些系統允許用戶在每次建立連接時設置這些變量,有些系統規定只有在系統啟動時才能設置。比如在linux中,這些變量分別對應net.ipv4.tcp_keepalive_time、net.ipv4.tcp_keepalive_intvl、net.ipv4.tcp_keepalive_probes,默認設置是7200秒、75秒和9次探測。

保活探測報文為一個空報文段(只包含1字節)。它的序列號等於對方主機發送的ACK報文的最大序列號減1,因為這一序列號的數據段已經被成功接收,所以不會對到達的報文段造成影響,但探測報文返回的響應可以確定連接是否仍在工作。需要注意的是,探測及其響應報文丟失時不會進行重傳。

書中的三個案例:

(案例一:正常連接 -> 另一端突然奔潰,本例中將保活時間設置為7000ms/7s,保活時間間隔設置為1s,在確認連接斷開之前(62.120s),客戶端會發送10個間隔為1秒的保活探測報文,最后連接斷開)

 

(案例二:另一端奔潰后重啟,本例中將保活時間設置為12000ms/2min,最后是另一端重啟后響應一個RST報文段,連接斷開)

(案例三:另一端不可達,本例中將保活時間設置為12000ms/2min,到達保活探測數后仍未收到響應,連接斷開)

 

參考:

《TCP IP 詳解卷1:協議》

RFC官方文檔


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM