【TCP/IP】四次揮手的過程及原因

四次揮手都做什麼?

TCP的連接是全雙工的,所以連接的拆除需要單獨將兩個通道分別拆除,而四次揮手所做的事情就是拆除兩條通道釋放資源

TCP 提供了連接的一端結束他的發送後,還能接收來自另一端數據的能力,也就是所謂的半關閉。

這裏以Client作爲主動發起端,Server作爲被動關閉端。

第一步,Client主動發起一個Req給Server,裏面包含FIN標識位=1,CLient的Seq序列號N,表示的是當前Client在該連接上的當前序列號。

第二步,Server端在收到這個含有FIN的Req消息之後,校驗無誤之後會立馬回覆ACK消息給CLient端,消息內部包含ACK標誌位爲1,同時Seq號碼是FIN的請求消息的Seq號+1。此時的Sever同時會主動發個結束標識給Server上面的應用層程序,應用層程序可以決定是立馬結束,還是等到服務其上面的該連接中的數據處理完了之後,在發送FIN消息給Client來關掉另外的一半連接。

第三步,Server端在處理完該連接上面的Pending住的數據之後,應用程序會close這個連接。Client會主動發起FIN的Req消息給Client端。消息內部帶有,FIN=1的結束符標識位,以及Server端的Seq序列號。

第四步,Client端在收到對應的FIN消息之後,會主動通知應用層程序,告知這個連接現在需要關閉了。然後,Client會回覆ACK消息給Server,以便斷開另外一個方向的通道,這個消息包含ACK=1的標識位和FIN的REQ帶過來的Seq+1。

爲什麼需要四次揮手?

因爲TCP是一個全雙工協議,必須單獨拆除每一條信道。4次揮手的目的是終止數據傳輸,並回收資源,此時兩個端點兩個方向的序列號已經沒有了任何關係,必須等待兩方向都沒有數據傳輸時才能拆除虛鏈路,不像初始化時那麼簡單,發現SYN標誌就初始化一個序列號並確認SYN的序列號。因此必須單獨分別在一個方向上終止該方向的數據傳輸。

如果是三次揮手,會怎麼樣?三次的話,被動關閉端在收到FIN消息之後,需要同時回覆ACK和Server端的FIN消息。如果Server端在該連接上面並沒有Pending的消息要處理,那麼是可以的,如果Server端還需要等待一段時間纔可以關閉另外一個方向的連接,那麼這樣的三次揮手就不能滿足條件。

四次揮手的狀態轉換?

Client端:

ESTABLISHED---發送FIN給Server-->FIN_WAIT_1---接收到Server端的FIN對應的ACK-->FIN_WAIT_2---收到Server端發送過來的FIN消息-->FIIN_WAIT--2MSL之後會進入-->CLOSED

Server端:

ESTABLISHED---接收到Client端的FIN->CLOSED_WAIT--Server端的應用程序關閉發送FIN--> LAST_ACK---收到Client對於FIN的ACK響應-->FIIN_WAIT---->CLOSED

其中四次揮手與Scoket函數的對應關係如下所示:


四次揮手失敗了會怎麼樣?

四次揮手裏面,最經典的場景,是Client處於TIME_WAIT之後的2MSL的時間處理。(備註:MSL是TCP報文裏面最大生存時間,它是任何報文段被丟棄前在網絡內的最長時間。)

設置2MSL的目的是爲了處理,Server端在重傳最後一個FIN的時候,Client能夠發送最後一個ACK的時間。

這個時間段內,不管是Client端還是Server端,最好都不要重用這個TCP的端口,否則的話,可能會導致根據這個端口新建立的連接被錯誤的關掉,詳細情況如下所示:

step1:Server發送給Client的最後一個FIN,Client收到了,也發了ACK給Server,但是Server並沒有收到這個ACK。step2:於是CLient複用了這個Port號,於是新建了一條連接,這裏假設叫newConnection。step3:Server在此過程中已經發送了重傳的FIN給Client,Client上面剛建立完成的newConnection就會再次被關掉。

參考資料:

https://blog.csdn.net/qq_34501940/article/details/51119726

https://blog.csdn.net/varyall/article/details/80348850

TCP/IP詳解 卷1


灰子做於二零一九年一月二十一日。

【原創作品,歡迎分享,請勿轉載,謝謝尊重!!】


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