碼仔漫畫:如何跟女朋友 “四次揮手”
本文轉載自微信公眾號「碼個蛋」,作者碼仔。轉載本文請聯系碼個蛋公眾號。
MSL 是 Maximum Segment Lifetime,報文最大生存時間,它是任何報文在網絡上存在的最長時間,超過這個時間報文將被丟棄。因為 TCP 報文基于是 IP 協議的,而 IP 頭中有一個 TTL 字段,是 IP 數據報可以經過的最大路由數,每經過一個處理他的路由器此值就減 1,當此值為 0 則數據報將被丟棄,同時發送 ICMP 報文通知源主機。
MSL 與 TTL 的區別:MSL 的單位是時間,而 TTL 是經過路由跳數。所以 MSL 應該要大于等于 TTL 消耗為 0 的時間,以確保報文已被自然消亡。
TIME_WAIT 等待 2 倍的 MSL,比較合理的解釋是:網絡中可能存在來自發送方的數據包,當這些發送方的數據包被接收方處理后又會向對方發送響應,所以一來一回需要等待 2 倍的時間。
比如如果被動關閉方沒有收到斷開連接的最后的 ACK 報文,就會觸發超時重發 Fin 報文,另一方接收到 FIN 后,會重發 ACK 給被動關閉方, 一來一去正好 2 個 MSL。
2MSL 的時間是從客戶端接收到 FIN 后發送 ACK 開始計時的。如果在 TIME-WAIT 時間內,因為客戶端的 ACK 沒有傳輸到服務端,客戶端又接收到了服務端重發的 FIN 報文,那么 2MSL 時間將重新計時。
在 Linux 系統里 2MSL 默認是 60 秒,那么一個 MSL 也就是 30 秒。Linux 系統停留在 TIME_WAIT 的時間為固定的 60 秒。
其定義在 Linux 內核代碼里的名稱為 TCP_TIMEWAIT_LEN:
- #define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT
- state, about 60 seconds */
如果要修改 TIME_WAIT 的時間長度,只能修改 Linux 內核代碼里 TCP_TIMEWAIT_LEN 的值,并重新編譯 Linux 內核。
需要 TIME-WAIT 狀態,主要是兩個原因:
- 防止具有相同「四元組」的「舊」數據包被收到;
- 保證「被動關閉連接」的一方能被正確的關閉,即保證最后的 ACK 能讓被動關閉方接收,從而幫助其正常關閉;