Tcp->三次握手和四次揮手

TCP協議中的三次握手和四次揮手

建立TCP需要三次握手才能建立,而斷開連接則需要四次握手。整個過程如下圖所示:

先來看看如何建立連接的。



首先Client端發送連接請求報文,Server段接受連接後回覆ACK報文,併爲這次連接分配資源。Client端接收到ACK報文後也向Server段發生ACK報文,並分配資源,這樣TCP連接就建立了。

那如何斷開連接呢?簡單的過程如下:


【注意】中斷連接端可以是Client端,也可以是Server端。

假設Client端發起中斷連接請求,也就是發送FIN報文。Server端接到FIN報文後,意思是說"我Client端沒有數據要發給你了",但是如果你還有數據沒有發送完成,則不必急着關閉Socket,可以繼續發送數據。所以你先發送ACK,"告訴Client端,你的請求我收到了,但是我還沒準備好,請繼續你等我的消息"。這個時候Client端就進入FIN_WAIT狀態,繼續等待Server端的FIN報文。當Server端確定數據已發送完成,則向Client端發送FIN報文,"告訴Client端,好了,我這邊數據發完了,準備好關閉連接了"。Client端收到FIN報文後,"就知道可以關閉連接了,但是他還是不相信網絡,怕Server端不知道要關閉,所以發送ACK後進入TIME_WAIT狀態,如果Server端沒有收到ACK則可以重傳。(主動斷開鏈接的一方爲什麼要進入TIME_WAIT狀態)“,Server端收到ACK後,"就知道可以斷開連接了"。Client端等待了2MSL後依然沒有收到回覆,則證明Server端已正常關閉,那好,我Client端也可以關閉連接了。Ok,TCP連接就這樣關閉了!

整個過程Client端所經歷的狀態如下:


而Server端所經歷的過程如下:轉載請註明:blog.csdn.net/whuslei


【注意】 在TIME_WAIT狀態中,如果TCP client端最後一次發送的ACK丟失了,它將重新發送。TIME_WAIT狀態中所需要的時間是依賴於實現方法的。典型的值爲30秒、1分鐘和2分鐘。等待之後連接正式關閉,並且所有的資源(包括端口號)都被釋放。

【問題1】爲什麼連接的時候是三次握手,關閉的時候卻是四次握手?
答:因爲當Server端收到Client端的SYN連接請求報文後,可以直接發送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。但是關閉連接時,當Server端收到FIN報文時,很可能並不會立即關閉SOCKET,所以只能先回復一個ACK報文,告訴Client端,"你發的FIN報文我收到了"。只有等到我Server端所有的報文都發送完了,我才能發送FIN報文,因此不能一起發送。故需要四步握手。

【問題2】爲什麼TIME_WAIT狀態需要經過2MSL(最大報文段生存時間)才能返回到CLOSE狀態?

答:雖然按道理,四個報文都發送完畢,我們可以直接進入CLOSE狀態了,但是我們必須假象網絡是不可靠的,有可以最後一個ACK丟失。所以TIME_WAIT狀態就是用來重發可能丟失的ACK報文。

參考:http://blog.csdn.net/whuslei/article/details/6667471/

TCP/IP狀態變遷圖:

  

各狀態詳細描述:

  CLOSED:表示初始狀態。對服務端和C客戶端雙方都一樣。

 

  LISTEN:表示監聽狀態。服務端調用了listen函數,可以開始accept連接了。

 

  SYN_SENT:表示客戶端已經發送了SYN報文。當客戶端調用connect函數發起連接時,首先發SYN給服務端,然後自己進入SYN_SENT狀態,並等待服務端發送ACK+SYN。

 

  SYN_RCVD:表示服務端收到客戶端發送SYN報文。服務端收到這個報文後,進入SYN_RCVD狀態,然後發送ACK+SYN給客戶端。

 

  ESTABLISHED:表示連接已經建立成功了。服務端發送完ACK+SYN後進入該狀態,客戶端收到ACK後也進入該狀態。

 

  FIN_WAIT_1:表示主動關閉連接。無論哪方調用close函數發送FIN報文都會進入這個這個狀態。

 

  FIN_WAIT_2:表示被動關閉方同意關閉連接。主動關閉連接方收到被動關閉方返回的ACK後,會進入該狀態。

 

  TIME_WAIT:表示收到對方的FIN報文併發送了ACK報文,就等2MSL後即可回到CLOSED狀態了。如果FIN_WAIT_1狀態下,收到對方同時帶FIN標誌和ACK標誌的報文時,可以直接進入TIME_WAIT狀態,而無須經過FIN_WAIT_2狀態。

 

  CLOSING:表示雙方同時關閉連接。如果雙方几乎同時調用close函數,那麼會出現雙方同時發送FIN報文的情況,就會出現CLOSING狀態,表示雙方都在關閉連接。

 

  CLOSE_WAIT:表示被動關閉方等待關閉。當收到對方調用close函數發送的FIN報文時,迴應對方ACK報文,此時進入CLOSE_WAIT狀態。

 

  LAST_ACK:表示被動關閉方發送FIN報文後,等待對方的ACK報文狀態,當收到ACK後進入CLOSED狀態。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章