Linux

如何在 TIME_WAIT 中強制關閉套接字?

  • August 19, 2015

我在 linux 上執行一個有時會崩潰的特定程序。如果您在那之後快速打開它,它會在套接字 49201 上偵聽,而不是像第一次那樣偵聽 49200。netstat 顯示 49200 處於 TIME_WAIT 狀態。

是否有可以執行的程序立即強制套接字移出 TIME_WAIT 狀態?

實際上有一種方法可以終止連接 - killcx。他們聲稱它可以在任何連接狀態下工作(我尚未驗證)。您需要知道發生通信的介面,預設情況下它似乎假定為 eth0。

更新:另一種解決方案是刀具,它出現在一些 linux 發行版的儲存庫中。

/etc/init.d/networking restart

讓我詳細說明。傳輸控制協議 (TCP) 被設計為兩個端點(程序)之間的雙向、有序和可靠的數據傳輸協議。在這種情況下,術語可靠意味著如果數據包在中間失去,它將重新傳輸數據包。TCP 通過發回從對等方接收到的單個或一系列數據包的確認 (ACK) 數據包來保證可靠性。

對於終止請求/響應等控制信號也是如此。RFC 793將 TIME-WAIT 狀態定義如下:

TIME-WAIT - 表示等待足夠的時間以確保遠端 TCP 收到其連接終止請求的確認。

請參見以下 TCP 狀態圖: 替代文字

TCP 是一種雙向通信協議,因此在建立連接時,客戶端和伺服器之間沒有區別。此外,任何一個都可以呼叫退出,並且兩個對等方都需要就關閉達成一致,以完全關閉已建立的 TCP 連接。

讓我們稱第一個將退出者稱為主動接近者,而另一個同伴稱為被動接近者。當主動關閉器發送 FIN 時,狀態進入 FIN-WAIT-1。然後它接收到已發送 FIN 的 ACK,狀態進入 FIN-WAIT-2。一旦它也從被動關閉器接收到 FIN,主動關閉器將 ACK 發送到 FIN 並且狀態進入 TIME-WAIT。如果被動關閉器沒有收到對第二個 FIN 的 ACK,它將重新發送 FIN 數據包。

RFC 793將 TIME-OUT 設置為最大段生命週期的兩倍,即 2MSL。由於 MSL(數據包可以在 Internet 上漫遊的最長時間)設置為 2 分鐘,因此 2MSL 為 4 分鐘。由於沒有對 ACK 的 ACK,因此如果主動關閉者正確遵守 TCP/IP 協議,則只能等待 4 分鐘,以防被動發送者沒有收到對其 FIN 的 ACK(理論上) .

實際上,失去數據包可能很少見,如果這一切都發生在 LAN 內或單台機器內,則非常罕見。

要逐字回答問題,如何在 TIME_WAIT 中強制關閉套接字?,我仍然會堅持我原來的答案:

/etc/init.d/networking restart

實際上,我會對其進行程式,使其使用 WMR 提到的 SO_REUSEADDR 選項忽略 TIME-WAIT 狀態。 SO_REUSEADDR 究竟是做什麼的?

這個套接字選項告訴核心,即使這個埠很忙(處於

TIME_WAIT 狀態),繼續並重用它。如果它很忙,但處於另一個狀態,您仍然會收到地址已在使用錯誤。如果您的伺服器已關閉,然後在其埠上的套接字仍處於活動狀態時立即重新啟動,這將很有用。您應該知道,如果有任何意外數據進入,它可能會使您的伺服器感到困惑,但是雖然這是可能的,但不太可能。

引用自:https://serverfault.com/questions/329845