TCP漫談之爲啥需要timewait狀態

tcp的狀態狀態轉化圖如下所示,其中Time_awit狀態是CLOSED之前的一個狀態,等待2個MSL時間。
在這裏插入圖片描述
爲啥需要time_awit狀態呢?爲啥不直接進入closed狀態呢?這樣不就能更快的釋放資源給新的連接使用了嗎?而是還需要等待2MSL(linux默認)時間。
有兩個原因,第一個原因是爲了防止“迷路的數據包”,如下圖所示,如果在第一個連接裏面第三個數據包由於底層網絡故障延遲送達。等待新的連接建立後,這個遲到的數據包纔到達,那麼將會導致接收數據紊亂。
在這裏插入圖片描述
第二個原因則更加簡單,如果因爲最後一個ack丟失,那麼對方將一直處於last ack狀態,如果此時重新發起新的連接,對方將返回RST包拒絕請求,將會導致無法建立新連接。
在這裏插入圖片描述
爲此,設計了time_awit狀態。如果在高併發情況下,如果能將time_awit的tcp複用
那麼便可以極大的提高併發效率,time_awit的tcp複用是指可以將處於time_awit狀態的連接重複利用起來,從time_awit轉化爲established,繼續使用。linux內核通過net.ipv4.tcp_tw_reuse參數控制是否開啓time_awit狀態複用。那麼讀者可能很好奇,之前不是說time_awit設計之初是爲了解決上面兩個問題的嗎?如果直接複用不是會導致上面兩個問題嗎?這裏先介紹linux默認開啓的一個tcp時間戳策略net.ipv4.tcp_timestamps = 1.
在這裏插入圖片描述
時間戳開啓後,針對第一個迷路數據包的問題,由於晚到數據包的時間戳過早會被直接丟棄,不會導致新連接數據包紊亂。針對第二個問題,當開啓reuse後,當對方處於last-ack狀態時,發送syn包會返回FIN,ACK包,然後客戶端發送RST讓服務端關閉請求,從而客戶端便可以再次發送syn建立新的連接了。
最後還需要提醒讀者的是,linux 4.1內核版本之前除了tcp_tw_reuse以外,還有一個參數tcp_tw_recycle,這個參數就是強制回收time_wait狀態的連接,它會導致NAT環境丟包,所以不建議開啓,這個在之前的blog已經分享過了。

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