日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

TCP/IP学习笔记(五)TCP的保活定时器

發布時間:2024/4/19 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 TCP/IP学习笔记(五)TCP的保活定时器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

正常情況下,TCP連接的終止需要經歷四次揮手階段,體現在代碼上就是某一端主動調用close函數關閉套接字,隨后TCP向對端發送FIN位被置為1的報文段標志著連接的結束,同時對端響應應答報文段,并在隨后的某一時刻同樣調用close函數,發送FIN報文段,當確認完成后就標志著TCP連接正常終止。

然而,考慮一種情況,在TCP連接建立成功后,客戶端主機突然崩潰(斷電,斷網等),導致客戶端的TCP還沒來得及將FIN發送給服務器就已經關閉了(或者由于斷網導致FIN無法到達對端),而服務器通常又不會主動發送數據給客戶端。在這種情況下,客戶端已經關閉,服務器卻不知道,依然保持著維護一個連接應該有的所有東西(包括文件描述符,TCP緩沖區等),一個還好,當有大量這種半開連接存在于服務器中,會造成大量的浪費

保活定時器

在TCP協議中,有一個被稱作保活定時器的組件,它就是為了解決上述問題被引進的。該定時器的原理也非常簡單,當通信雙方在定時器規定的這段時間內沒有進行數據交互,那么開啟保活選項的一端TCP就會發送一個探查報文段,當對端TCP接收到報文段發現這是個探查報文時,會響應應答信息。

上述過程是TCP獨立于應用程序進行的,應用程序不會知道探查報文的發送和到達

此外,保活定時器的定時時間是兩小時,是系統級別的參數,可以更改,但是最好不要更改,會影響到系統進程

如果一個連接在兩小時內沒有任何數據交互,則服務器就向客戶端發送一個探查報文段(假設服務器開啟保活定時器),此時客戶端主機有四中可能的狀態

  • 客戶端主機依然正常運行,并從服務器可達。客戶端TCP接收到探查報文段并返回應答報文段,此時服務器知道客戶端依然存在,所以重置保活定時器。另外,如果在定時器溢出之前進行了數據交互,定時器也會被重置
  • 客戶端主機已崩潰,已關閉或者正在重啟。這種情況下,服務器無法得到客戶端回應,探測報文段在75秒后超時,服務器總共發送10個這樣的探測,每個間隔75秒(超時重傳)。如果服務器還是沒有接收到客戶端的應答,就認為客戶端已經關閉,隨后告知應用程序,關閉連接(套接字變為可讀,讀取錯誤信息為“連接超時”)
  • 客戶端主機崩潰并已重啟。在這種情況下,由于客戶端重啟了系統,所有的TCP連接信息都已經丟失,當接收到服務器的探測報文段時,客戶端在本機中無法找到匹配的TCP連接,隨后發送一個復位報文段,服務器接收到復位報文段后告知應用程序,關閉連接(套接字變為可讀,讀取錯誤信息為“連接被重置”)
  • 客戶端主機正常運行,但是從服務器不可達。這種情況通常是由于傳輸路徑中的某個路由器關閉導致,此種情況與客戶端主機崩潰并正在重啟時處理方式相同,因為都是收不到應答

下面通過tcpdump抓包分析后三種情況,分析時假設崩潰的一方是服務器,隨后觀察客戶端TCP探查報文段發送情況

另一端主機崩潰,已關閉或正在重啟

借用<TCP/IP詳解>中的示例,建立TCP連接后等待四小時后斷開服務器以太網電纜,觀察客戶端探查報文段發送情況

觀察tcpdump輸出結果(省略了三次握手的報文段)

結果中前三行表示客戶端發送”hello world”報文段,服務器對該報文段進行應答并回顯”hello world”報文段,客戶端對服務器的報文段進行應答

隨后的四小時內,客戶端先后兩次嘗試探查服務器是否關閉,首先看到的是一個ARP請求和ARP應答,隨后發送探查報文段并得到回應

接下來斷開服務器以太網電纜,并在兩個小時之后又進行探查,然而由于服務器主機以太網斷開,無法回應客戶端ARP請求,隨后的每75秒進行一次超時重傳,最終放棄,錯誤碼為“連接超時”

ARP請求主要用來獲取對端的物理地址,首先需要知道對方地址,才能發送數據,而由于服務器以太網斷開無法回應ARP請求,所以上述過程沒有看到TCP報文的發送就已經可以確認對方崩潰

另一端崩潰并重新啟動

借用<TCP/IP詳解>中的示例,在建立連接后將服務器以太網斷開,重新啟動,然后再連接到網絡上。由于服務器已重啟,對于之前所有的TCP連接信息都已丟失,當接收到客戶端發來的探查報文段時,會回復一個復位報文段

觀察tcpdump輸出結果(省去了連接建立過程)

可以看到,由于服務器以太網連接正常,ARP請求得到應答,隨后客戶端發送探查報文段,但是服務器已經重啟,沒有關于該連接的信息,只能返回一個復位報文段

另一端不可達

再次使用<TCP/IP詳解>中的示例,連接建立后先確認可以正常通訊,等待兩小時后發送探查報文并收到回應,隨后將中間鏈路斷開,觀察結果

觀察tcpdump輸出結果(省略掉連接的建立過程)

前三行是正常的回顯流程,4,5行是兩小時后的探查報文,隨后的若干行由于中間鏈路被斷開,引發來自客戶端主機路由器的ICMP不可達錯誤,隨后又連續發送了9個探查報文,最終返回給應用程序“沒有到達主機的路由”錯誤

SO_KEEPALIVE選項

linux內核中有關于保活定時器的三個參數

  • tcp_keepalive_time,指空閑時長,tcp_keepalive_time時間沒有數據交互就發送探查報文段,默認7200s(2h)
  • tcp_keepalive_intvl,發送探查報文段后如果沒有收到應答,tcp_keepalive_intvl時間后會重新發送,默認是75s
  • tcp_keepalive_probes,發送探查報文沒有收到應答后繼續發送的次數,發送tcp_keepalive_probes次后認為對方已關閉,默認是9次

如果要更改,可以在/etc/sysctl.conf文件中寫入(值自己設置)

net.ipv4.tcp_keepalive_time = net.ipv4.tcp_keepalive_probes = net.ipv4.tcp_keepalive_intvl =

保存后執行sysctl -p生效。這里是直接修改了內核參數,此后所有的進程的SO_KEEPALIVE時間都被更改

但是由于上述三個參數都是系統級別的參數,也就是說如果更改,那么就會影響開啟了SO_KEEPALIVE的系統進程,可能造成意想不到的后果

如果只想在某個應用程序中修改時間,除了開啟SO_KEEPALIVE選項外,需要同時設計三個TCP參數

#include <netinet/tcp.h>/* fd : 套接字描述符* time : 空閑時間,當time時間沒有數據交互的話就發送探查報文 */ int enableKeepAlive(int fd, int time) {int val = 1;::setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val));val = time; //空閑時間::setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val));val = time / 3; //探查報文的發送間隔::setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &val, sizeof(val));val = 3; //探查報文的發送次數::setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &val, sizeof(val)); }

總結

以上是生活随笔為你收集整理的TCP/IP学习笔记(五)TCP的保活定时器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。