1.time_wait狀態是什麼java
2.爲何會有time_wait狀態網絡
3.哪一方會有time_wait狀態socket
4.怎樣避免time_wait狀態佔用資源tcp
通訊雙方創建TCP鏈接後,主動關閉鏈接的一方就會進入TIME_WAIT狀態。操作系統
客戶端主動關閉鏈接時,會發送最後一個ack後,而後會進入TIME_WAIT狀態,再停留2個MSL時間(後有MSL的解釋),進入CLOSED狀態。 server
1)可靠地實現TCP全雙工鏈接的終止進程
TCP協議在關閉鏈接的四次握手過程當中,最終的ACK是由主動關閉鏈接的一端(後面統稱A端)發出的,若是這個ACK丟失,對方(後面統稱B端)將重發出最終的FIN,所以A端必須維護狀態信息(TIME_WAIT)容許它重發最終的ACK。若是A端不維持TIME_WAIT狀態,而是處於CLOSED 狀態,那麼A端將響應RST分節,B端收到後將此分節解釋成一個錯誤(在java中會拋出connection reset的SocketException)。圖片
於是,要實現TCP全雙工鏈接的正常終止,必須處理終止過程當中四個分節任何一個分節的丟失狀況,主動關閉鏈接的A端必須維持TIME_WAIT狀態 。ip
2)容許老的重複分節在網絡中消逝資源
TCP分節可能因爲路由器異常而「迷途」,在迷途期間,TCP發送端可能因確認超時而重發這個分節,迷途的分節在路由器修復後也會被送到最終目的地,這個遲到的迷途分節到達時可能會引發問題。在關閉「前一個鏈接」以後,立刻又從新創建起一個相同的IP和端口之間的「新鏈接」,「前一個鏈接」的迷途重複分組在「前一個鏈接」終止後到達,而被「新鏈接」收到了。爲了不這個狀況,TCP協議不容許處於TIME_WAIT狀態的鏈接啓動一個新的可用鏈接,由於TIME_WAIT狀態持續2MSL,就能夠保證當成功創建一個新TCP鏈接的時候,來自舊鏈接重複分組已經在網絡中消逝。
MSL就是maximum segment lifetime(最大分節生命期),這是一個IP數據包能在互聯網上生存的最長時間,超過這個時間IP數據包將在網絡中消失 。MSL在RFC 1122上建議是2分鐘,而源自berkeley的TCP實現傳統上使用30秒。
TIME_WAIT狀態維持時間是兩個MSL時間長度,也就是在1-4分鐘。Windows操做系統就是4分鐘。
假設是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地址。