閱讀995 返回首頁    go 阿裏雲 go 技術社區[雲棲]


linux 網絡編程之TIME_WAIT狀態

                                                          Linux 網絡編程之TIME_WAIT狀態

 

 

                                                       

 

剛剛開始看TCP socket的4次握手終止流程圖的時候,對於最後的TIME_WAIT狀態不是很理解.現在在回過頭來研究,發現TIME_WAIT狀態是一個很微妙狀態.之所以設計TIME_WAIT狀態的原因有2個原因:

 

  1. 使得TCP的全雙工連接能夠可靠的終止.
  2.  使得連接終止後網絡上任然殘餘的發送給該連接的數據被丟棄而不至於被新連接接收.

在具體詳解這兩個原因之前,我們需要理解MSL(maxinum segment lifetime)這個概念.

每一個TCP 都必須有一個MSL值.這個值一般是2分鍾,但也不是固定的,不同的係統不一樣.無論是否出錯或者連接被斷開,總之,一個數據包在網路上能停留的最大時間是MSL.也就是說MSL是數據包的生命周期時間.操作這個時間,該數據包將會被丟棄而不被發送.而TIME_WAIT狀態持續的時間是MSL的兩倍,也就是2MSL時間.

 

  • TCP的全雙工連接能夠被可靠終止

TCP的可靠終止需要經過4次握手終止.如上圖所示:首先,client 主動close,導致FIN發送給server,server接收到FIN後,給client回複一個ACK,之後,server會關閉和client的連接,即向client發送一個FIN,client接收到FIN之後,會發送一個ACK給server.此時client就進入TIME_WAIT狀態.如果server沒有收到ACK,server會重新發送一個FIN信息給client,client會重發ACK,server然後繼續等待client發送一個ACK.這樣保證了雙方的可靠終止.2端都知道對方已經終止了.那麼,在這個TIME_WAIT時間中,可以重發ACK,如果client沒有收到FIN信息,則TCP會向server發送一個RST信息,這個信息會被server解釋成error.

 

  • 連接終止後網絡上任然殘留的發送到該連接的數據被丟棄而不至於被新連接接收.

舉個例子:

在10.12.24.48 port:21和206.8.16.32 port:23(不必關心哪一端是server哪一端是client)之間建立了一個TCP連接A.然後此鏈接A被close掉了.然後此時又在10.12.24.48 port:21和206.8.16.32 port:23(不必關心哪一端是server哪一端是client)之間建立了一個新的TCP連接B.很可能A和B連接是有不同的應用程序建立的.那麼,當我們close掉A之後,網絡上很有可能還有屬於A連接兩端的數據m正在網路上被傳送.而此時A被close掉了,重新建立了B連接,由於A和B連接的地址和端口都是一樣的.這樣,m數據就會被最終發送到B連接的兩端.這樣就造成了混亂,B接收到了原本數據A的數據.處於TIME_WAIT狀態的連接會禁止新的同樣的連接(如A,B)連接被建立.除非等到TIME_WAIT狀態結束,也就是2MSL時間之後.其中,一個MSL時間是為了網絡上的正在被發送到該鏈接的數據被丟棄,另一個MSL使得應答信息被丟棄.這樣,2MSL之後,保證重新建立的所得到的數據絕對不會是發往就連接的數據.

 

 


版權申明:
轉載文章請注明原文出處https://blog.csdn.net/feiyinzilgd/archive/2010/09/19/5894446.aspx

並請聯係譚海燕本人或者前往譚海燕個人主頁留言

最後更新:2017-04-02 06:51:26

  上一篇:go 關於MAP文件的使用
  下一篇:go C Runtime Library、C++ Runtime Library、Windows API 和 C++標準四者之間的關係