第一:問題分析 TIME_WAIT狀態做用!html
四次握手含義是:個人理解 服務器
TIME_WAIT:目的是讓對端關閉以後,我在關閉,假如我先退出,對端在執close時候網絡
沒法收到發送的確認ack,這樣拋出異常。就像connect同樣,對端不存在 確定出錯socket
TIME_WAIT狀態原理tcp
----------------------------spa
通訊雙方創建TCP鏈接後,主動關閉鏈接的一方就會進入TIME_WAIT狀態。設計
客戶端主動關閉鏈接時,會發送最後一個ack後,而後會進入TIME_WAIT狀態,再停留2個MSL時間(後有MSL的解釋),進入CLOSED狀態。code
下圖是以客戶端主動關閉鏈接爲例,說明這一過程的。orm
TIME_WAIT狀態存在的理由server
----------------------------
TCP/IP協議就是這樣設計的,是不可避免的。主要有兩個緣由:
1)可靠地實現TCP全雙工鏈接的終止
TCP協議在關閉鏈接的四次握手過程當中,最終的ACK是由主動關閉鏈接的一端(後面統稱A端)發出的,若是這個ACK丟失,對方(後面統稱B端)將重發出最終的FIN,所以A端必須維護狀態信息(TIME_WAIT)容許它重發最終的ACK。若是A端不維持TIME_WAIT狀態,而是處於CLOSED 狀態,那麼A端將響應RST分節,B端收到後將此分節解釋成一個錯誤
於是,要實現TCP全雙工鏈接的正常終止,必須處理終止過程當中四個分節任何一個分節的丟失狀況,主動關閉鏈接的A端必須維持TIME_WAIT狀態 。
2)容許老的重複分節在網絡中消逝
TCP分節可能因爲路由器異常而「迷途」,在迷途期間,TCP發送端可能因確認超時而重發這個分節,迷途的分節在路由器修復後也會被送到最終目的地,這個遲到的迷途分節到達時可能會引發問題。在關閉「前一個鏈接」以後,立刻又從新創建起一個相同的IP和端口之間的「新鏈接」,「前一個鏈接」的迷途重複分組在「前一個鏈接」終止後到達,而被「新鏈接」收到了。爲了不這個狀況,TCP協議不容許處於TIME_WAIT狀態的鏈接啓動一個新的可用鏈接,由於TIME_WAIT狀態持續2MSL,就能夠保證當成功創建一個新TCP鏈接的時候,來自舊鏈接重複分組已經在網絡中消逝。
問題2:
何時結束呢.我在這裏再講到一個新名詞:2MSL等待狀態,其實TIME_WAIT就是2MSL等待狀態,
爲何要設置這個狀態,緣由是有足夠的時間讓ACK包到達服務器端,若是服務器端沒收到ACK包,
超時了,而後從新發一個FIN包,直到服務器收到ACK 包.
第二:代碼驗證:
參考:
http://coderworm.com/%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/2013/11/13/socket-half-close.html
tcpclient狀態: ESTABLISHED -->TIME_WAIT --> [root@localhost socket]# netstat -anp |grep 9998 tcp 0 0 0.0.0.0:9998 0.0.0.0:* LISTEN 7267/./tcpserver tcp 0 0 127.0.0.1:9998 127.0.0.1:40604 ESTABLISHED 7292/./tcpserver tcp 0 0 127.0.0.1:40604 127.0.0.1:9998 ESTABLISHED 7291/./tcpclient [root@localhost socket]# netstat -anp |grep 9998 tcp 0 0 0.0.0.0:9998 0.0.0.0:* LISTEN 7267/./tcpserver tcp 0 0 127.0.0.1:40604 127.0.0.1:9998 TIME_WAIT - [root@localhost socket]# netstat -anp |grep 9998 tcp 0 0 0.0.0.0:9998 0.0.0.0:* LISTEN 7267/./tcpserver
參考:
http://www.360doc.com/content/10/1009/17/2245786_59637481.shtml
http://huoding.com/2014/11/06/383