TCP連接狀態與2MSL等待時間


1 連接狀態圖

TCP狀態

2 建立連接:三次握手,不使用DNS和使用DNS

不使用DNS

使用DNS

3 關閉連接-四次握手

關閉連接

連接雙方任何一方調用close()后,連接的兩個傳輸方向都關閉,不能再發送數據了。如果一方調用shutdown()則連接處於半關閉狀態,仍可接收對方發來的數據。

如果出現半關閉,例如客戶->服務器方向關閉。則服務器還可以發,客戶端還可以收。

協議規定主動關閉一方,進入FIN_WAIT_2->TIME_WAIT,必須等待2MSL(MSL為最大報文段生存時間,LWIP為1分鍾,windows為2分鍾)時間然后才進入CLOSED,刪除TCP控制塊。在2MSL等待時間內遲到的報文段將被拋棄。

如果我們在客戶端關閉一個連接然后又立刻建立連接(使用同一端口號),2MSL時間內之前連接的端口號不能使用,即使調用bind函數也將返回-1(綁定失敗),內核將自動分配一個新的端口號使用。通常情況下這個我們並不關心,因為客戶端的端口號我們並不關心,只要能用就可以。但是如果是服務器就不一樣了,服務器的端口一般是固定的,客戶端必須知道服務器的端口號才能建立連接,所以如果服務器端主動斷開連接時,就需要注意,或者做一些處理:不讓它等待2MSL后才可以使用,具體做法:使能SO_REUSEPORT(允許重用本地地址),可以通過調用setsockopt函數來使能。

2MSL等待的原因:報文段有生存時間,當連接關閉時,有可能收到遲到的報文段。這時,若立馬就建立新的連接(同一端口),那么新的連接就會接收遲到的報文,誤以為是發給自己的。另一個原因是可靠的實現全雙工連接的終止。

FIN_WAIT_2狀態我們已經發出了FIN,並且另一端也已對它進行確認。除非我們在實行半關閉,否則將等待另一端的應用層意識到它已收到一個文件結束符說明,並向我們發一個FIN來關閉另一方向的連接。只有當另一端的進程完成這個關閉,我們這端才會從FIN_WAIT_2狀態進入TIME_WAIT狀態。這意味着我們這端可能永遠保持這個狀態(FIN_WAIT_2,如果對方不發送FIN包)。另一端也將處於CLOSE_WAIT狀態,並一直保持這個狀態直到應用層決定進行關閉(調用close然后進入LAST_ACK)。


參考:http://www.cnblogs.com/mddblog/p/4565562.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM