"半連接"檢測的研究
所謂半開TCP連接,簡單地說就是發送了TCP連接請求,但還沒有得到對方應答的狀態(實際上要復雜些),也就是連接尚未完全建立起來,雙方還無法進行通信交互的狀態。
我這裡討論的"半連接"是在tcp已經建立後,進行通訊的過程中,一方的連接因為異常斷掉,另一方沒有收到任何數據包,仍處於ESTABLISHED的狀態。
半連接占用了tcp的資源,在大量並發的網站會使服務器資源耗盡而導致服務器的假死甚至癱瘓。另半連接的狀態下,tcp協議棧仍能正常工作,應用層的程序不能覺察。
檢測半連接的方法,一般使用tcp提供的keepalive的屬性,需要設置的選項包含;
setsockopt函數的選項,組合使用:
SOL_SOCKET, SO_KEEPALIVE
IPPROTO_TCP, TCP_KEEPIDLE
IPPROTO_TCP, TCP_KEEPINTVL
IPPROTO_TCP, TCP_KEEPCNT
當tcp協議棧檢測到半連接的狀態,會發送reset包,關閉連接,避免產生time_wait的狀態。
也用在業務層發送心跳包,檢測半連接,但是一定要有響應包,如果超時,就關閉連接。close會產生time_wait.
如果只發送心跳包是沒法檢測半連接的,因為應用層會把包發送到tcp的發送緩沖區,不返回錯誤信息。