TCP心跳包keep-alive --KeepAliveTime和KeepAliveInterval參數詳解


如果客戶端異常掉線或拔掉網線,那么在服務端會留下一個TCP連接,這個連接會變成死連接(經過測試,如果windows的TCP保持連接禁用的話,三個小時該死連接還不消失)。

如果大量客戶端並發,出現的死TCP連接過多,服務器內存和端口將會增加,直到占滿服務器的端口和耗盡內存為止。如果這樣的話,服務器無法健壯穩定的運行。

大家可以另開線程來監控客戶端連接,但是今天要給大家講解的不是這個方法,而是使用TCP協議自帶的心跳包功能解決這個問題。

大家先了解一下 TCP keep-alive原理

一個TCP keep-alive 包是一個簡單的ACK,該ACK包內容為一個比當前連接sequence number 小於一的包。

主機接受到這些ACKs會返回一個包含當前sequence number 的ACK包。

Keep-alives一般被用來驗證遠端連接是否有效。如果該連接上沒有其他數據被傳輸,或者更高level 的 keep-alives被傳送,keep-alives 在每隔KeepAliveTime被發送。(默認是 7,200,000 milliseconds ,也就是2個小時)。

如果沒有收到 keep-alive 應答,keep-alive 將在每 KeepAliveInterval 秒重發一次。KeepAliveInterval 默認為1秒。如 Microsoft 網絡功能中很多部分中采用的 NETBT 連接,更常見的是發送 NETBios keep-alives,所以,在 NetBios 連接中通常不發送TCP keep-alives。
TCP保持連接默認被禁用,但是微軟Sockets應用程序可以使用SetSockOpt函數去啟用他們。

請看下面的類

type
TCP_KeepAlive = record
    OnOff: Cardinal;
    KeepAliveTime: Cardinal; // 多長時間(ms)沒有數據就開始send心跳包
    KeepAliveInterval: Cardinal // 每隔多長時間(ms)send一個心跳包,發5次(系統值)
end;

KeepAliveTime: TCP連接多長時間(毫秒)沒有數據就開始發送心跳包,有數據傳遞的時候不發送心跳包
KeepAliveInterval: 失敗重試時,每隔多長時間(毫秒)發送一個心跳包,重試5次(系統默認值)

如果客戶端網絡中斷,服務器系統發送心跳包后,服務器會自動解除TCP連接。這一點,大家可以使用 netstat -p -tcp 命令查看。

 


免責聲明!

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



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