time_wait是個常問的問題。tcp網絡編程中最不easy理解的也是它的time_wait狀態,這也說明了tcp/ip四次揮手中time_wait狀態的重要性。
以下通過4個問題來描寫敘述它
問題
1.time_wait狀態是什么
2.為什么會有time_wait狀態
3.哪一方會有time_wait狀態
4.怎樣避免time_wait狀態占用資源
1.time_wait狀態是什么
簡單來說:time_wait狀態是四次揮手中server向client發送FIN終止連接后進入的狀態。
下圖為tcp四次揮手過程
![]()
能夠看到time_wait狀態存在於client收到serverFin並返回ack包時的狀態
當處於time_wait狀態時,我們無法創建新的連接,由於port被占用。
2.為什么會有time_wait狀態
time_wait存在的原因有兩點
1.可靠的終止TCP連接。
2.保證讓遲來的TCP報文段有足夠的時間被識別並丟棄。1.可靠的終止TCP連接,若處於time_wait的client發送給server確認報文段丟失的話,server將在此又一次發送FIN報文段,那么client必須處於一個可接收的狀態就是time_wait而不是close狀態。
2.保證遲來的TCP報文段有足夠的時間被識別並丟棄,linux 中一個TCPport不能打開兩次或兩次以上。當client處於time_wait狀態時我們將無法使用此port建立新連接,假設不存在time_wait狀態,新連接可能會收到舊連接的數據。time_wait持續的時間是2MSL,保證舊的數據能夠丟棄。由於網絡中的數據最大存在MSL(maxinum segment lifetime)
3.哪一方會有time_wait狀態
time_wait狀態是一般有client的狀態。
並且會占用port
有時產生在server端,由於server主動斷開連接或者發生異常
4.怎樣避免time_wait狀態占用資源
假設是client,我們一般不用操心,由於client一般選用暫時port。再次創建連接會新分配一個port。
除非指定client使用某port,只是一般不須要這么做。
假設是server主動關閉連接后異常終止。則由於它總是使用用一個知名serverport號,所以連接的time_wait狀態將導致它不能重新啟動。只是我們能夠通過socket的選項SO_REUSEADDR來強制進程馬上使用處於time_wait狀態的連接占用的port。
通過socksetopt設置后,即使sock處於time_wait狀態,與之綁定的socket地址也能夠馬上被重用。此外也能夠通過改動內核參數/proc/sys/net/ipv4/tcp_tw/recycle來高速回收被關閉的socket,從而是tcp連接根本不進入time_wait狀態,進而同意應用程序馬上重用本地的socket地址。