四次揮手

  1. 客戶端先發送FIN,進入FIN_WAIT1狀態

  2. 服務端收到FIN,發送ACK,進入CLOSE_WAIT狀態,客戶端收到這個ACK,進入FIN_WAIT2狀態

  3. 服務端發送FIN,進入LAST_ACK狀態

  4. 客戶端收到FIN,發送ACK,進入TIME_WAIT狀態,服務端收到ACK,進入CLOSE狀態

TIME_WAIT的狀態就是主動斷開的一方(這裏是客戶端),發送完最後一次ACK之後進入的狀態。並且持續時間還挺長的。客戶端TIME_WAIT持續2倍MSL時長,在linux體系中大概是60s,轉換成CLOSE狀態

TIME_WAIT

TIME_WAIT 是主動關閉鏈接時形成的,等待2MSL時間,約4分鐘。主要是防止最後一個ACK丟失。 由於TIME_WAIT 的時間會非常長,因此server端應儘量減少主動關閉連接

CLOSE_WAIT

CLOSE_WAIT是被動關閉連接是形成的。根據TCP狀態機,服務器端收到客戶端發送的FIN,則按照TCP實現發送ACK,因此進入CLOSE_WAIT狀態。但如果服務器端不執行close(),就不能由CLOSE_WAIT遷移到LAST_ACK,則系統中會存在很多CLOSE_WAIT狀態的連接。此時,可能是系統忙於處理讀、寫操作,而未將已收到FIN的連接,進行close。此時,recv/read已收到FIN的連接socket,會返回0。

爲什麼需要 TIME_WAIT 狀態?

假設最終的ACK丟失,server將重發FIN,client必須維護TCP狀態信息以便可以重發最終的ACK,否則會發送RST,結果server認爲發生錯誤。TCP實現必須可靠地終止連接的兩個方向(全雙工關閉),client必須進入 TIME_WAIT 狀態,因爲client可能面 臨重發最終ACK的情形。

爲什麼 TIME_WAIT 狀態需要保持 2MSL 這麼長的時間?

如果 TIME_WAIT 狀態保持時間不足夠長(比如小於2MSL),第一個連接就正常終止了。第二個擁有相同相關五元組的連接出現,而第一個連接的重複報文到達,干擾了第二個連接。TCP實現必須防止某個連接的重複報文在連接終止後出現,所以讓TIME_WAIT狀態保持時間足夠長(2MSL),連接相應方向上的TCP報文要麼完全響應完畢,要麼被 丟棄。建立第二個連接的時候,不會混淆。

TIME_WAIT 和CLOSE_WAIT狀態socket過多

如果服務器出了異常,百分之八九十都是下面兩種情況:

1.服務器保持了大量TIME_WAIT狀態

2.服務器保持了大量CLOSE_WAIT狀態,簡單來說CLOSE_WAIT數目過大是由於被動關閉連接處理不當導致的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章