1. 程式人生 > >詳解TCP連線的“三次握手”與“四次揮手”(下)

詳解TCP連線的“三次握手”與“四次揮手”(下)

上文連結:

詳解TCP連線的“三次握手”與“四次揮手”(上)

四、TCP的四次揮手(Four-Way Wavehand)

0.前言


對於"三次握手"我們耳熟能詳,因為其相對的簡單。但是,我們卻不常聽見“四次揮手”,就算聽過也未必能詳細地說明白它的具體過程。下面就為大家詳盡,直觀,完整地介紹“四次揮手”的過程。

1.“四次揮手”的詳解


所謂的四次揮手即TCP連線的釋放(解除)。連線的釋放必須是一方主動釋放,另一方被動釋放。以下為客戶端主動發起釋放連線的圖解:

揮手之前主動釋放連線的客戶端結束ESTABLISHED階段。隨後開始“四次揮手”:

(1)首先客戶端想要釋放連線,向伺服器端傳送一段TCP報文,其中:

標記位為FIN,表示“請求釋放連線“;

序號為Seq=U;

隨後客戶端進入FIN-WAIT-1階段,即半關閉階段。並且停止在客戶端到伺服器端方向上傳送資料,但是客戶端仍然能接收從伺服器端傳輸過來的資料。

注意:這裡不傳送的是正常連線時傳輸的資料(非確認報文),而不是一切資料,所以客戶端仍然能傳送ACK確認報文。

(2)伺服器端接收到從客戶端發出的TCP報文之後,確認了客戶端想要釋放連線,隨後伺服器端結束ESTABLISHED階段,進入CLOSE-WAIT階段(半關閉狀態)並返回一段TCP報文,其中:

標記位為ACK,表示“接收到客戶端傳送的釋放連線的請求”;

序號為Seq=V;

確認號為Ack=U+1,表示是在收到客戶端報文的基礎上,將其序號Seq值加1作為本段報文確認號Ack的值;

隨後伺服器端開始準備釋放伺服器端到客戶端方向上的連線。

客戶端收到從伺服器端發出的TCP報文之後,確認了伺服器收到了客戶端發出的釋放連線請求,隨後客戶端結束FIN-WAIT-1階段,進入FIN-WAIT-2階段


前"兩次揮手"既讓伺服器端知道了客戶端想要釋放連線,也讓客戶端知道了伺服器端了解了自己想要釋放連線的請求。於是,可以確認關閉客戶端到伺服器端方向上的連線了


(3)伺服器端自從發出ACK確認報文之後,經過CLOSED-WAIT階段,做好了釋放伺服器端到客戶端方向上的連線準備,再次向客戶端發出一段TCP報文,其中:

標記位為FIN,ACK,表示“已經準備好釋放連線了”。注意:這裡的ACK並不是確認收到伺服器端報文的確認報文。

序號為Seq=W;

確認號為Ack=U+1;表示是在收到客戶端報文的基礎上,將其序號Seq值加1作為本段報文確認號Ack的值。

隨後伺服器端結束CLOSE-WAIT階段,進入LAST-ACK階段。並且停止在伺服器端到客戶端的方向上傳送資料,但是伺服器端仍然能夠接收從客戶端傳輸過來的資料。

(4)客戶端收到從伺服器端發出的TCP報文,確認了伺服器端已做好釋放連線的準備,結束FIN-WAIT-2階段,進入TIME-WAIT階段,並向伺服器端傳送一段報文,其中:

標記位為ACK,表示“接收到伺服器準備好釋放連線的訊號”。

序號為Seq=U+1;表示是在收到了伺服器端報文的基礎上,將其確認號Ack值作為本段報文序號的值。

確認號為Ack=W+1;表示是在收到了伺服器端報文的基礎上,將其序號Seq值作為本段報文確認號的值。

隨後客戶端開始在TIME-WAIT階段等待2MSL

為什麼要客戶端要等待2MSL呢?見後文。

伺服器端收到從客戶端發出的TCP報文之後結束LAST-ACK階段,進入CLOSED階段。由此正式確認關閉伺服器端到客戶端方向上的連線。

客戶端等待完2MSL之後,結束TIME-WAIT階段,進入CLOSED階段,由此完成“四次揮手”。


後“兩次揮手”既讓客戶端知道了伺服器端準備好釋放連線了,也讓伺服器端知道了客戶端了解了自己準備好釋放連線了。於是,可以確認關閉伺服器端到客戶端方向上的連線了,由此完成“四次揮手”。


與“三次揮手”一樣,在客戶端與伺服器端傳輸的TCP報文中,雙方的確認號Ack和序號Seq的值,都是在彼此Ack和Seq值的基礎上進行計算的,這樣做保證了TCP報文傳輸的連貫性,一旦出現某一方發出的TCP報文丟失,便無法繼續"揮手",以此確保了"四次揮手"的順利完成。

2.”四次揮手“的動態過程


3.“四次揮手”的通俗理解


舉個栗子:把客戶端比作男孩,伺服器比作女孩。通過他們的分手來說明“四次揮手”過程。

  • "第一次揮手":日久見人心,男孩發現女孩變成了自己討厭的樣子,忍無可忍,於是決定分手,隨即寫了一封信告訴女孩。

  • “第二次揮手”:女孩收到信之後,知道了男孩要和自己分手,怒火中燒,心中暗罵:你算什麼東西,當初你可不是這個樣子的!於是立馬給男孩寫了一封回信:分手就分手,給我點時間,我要把你的東西整理好,全部還給你!

    男孩收到女孩的第一封信之後,明白了女孩知道自己要和她分手。隨後等待女孩把自己的東西收拾好。

  • “第三次揮手”:過了幾天,女孩把男孩送的東西都整理好了,於是再次寫信給男孩:你的東西我整理好了,快把它們拿走,從此你我恩斷義絕!

  • “第四次揮手”:男孩收到女孩第二封信之後,知道了女孩收拾好東西了,可以正式分手了,於是再次寫信告訴女孩:我知道了,這就去拿回來!

這裡雙方都有各自的堅持。

  • 女孩自發出第二封信開始,限定一天內收不到男孩回信,就會再發一封信催促男孩來取東西!
  • 男孩自發出第二封信開始,限定兩天內沒有再次收到女孩的信就認為,女孩收到了自己的第二封信;若兩天內再次收到女孩的來信,就認為自己的第二封信女孩沒收到,需要再寫一封信,再等兩天.....

倘若雙方信都能正常收到,最少只用四封信就能徹底分手!這就是“四次揮手”。

4.為什麼“握手”是三次,“揮手”卻要四次?


TCP建立連線時之所以只需要"三次握手",是因為在第二次"握手"過程中,伺服器端傳送給客戶端的TCP報文是以SYN與ACK作為標誌位的。SYN是請求連線標誌,表示伺服器端同意建立連線;ACK是確認報文,表示告訴客戶端,伺服器端收到了它的請求報文。

即SYN建立連線報文與ACK確認接收報文是在同一次"握手"當中傳輸的,所以"三次握手"不多也不少,正好讓雙方明確彼此資訊互通。

TCP釋放連線時之所以需要“四次揮手”,是因為FIN釋放連線報文與ACK確認接收報文是分別由第二次和第三次"握手"傳輸的。為何建立連線時一起傳輸,釋放連線時卻要分開傳輸?

  • 建立連線時,被動方伺服器端結束CLOSED階段進入“握手”階段並不需要任何準備,可以直接返回SYN和ACK報文,開始建立連線。
  • 釋放連線時,被動方伺服器,突然收到主動方客戶端釋放連線的請求時並不能立即釋放連線,因為還有必要的資料需要處理,所以伺服器先返回ACK確認收到報文,經過CLOSE-WAIT階段準備好釋放連線之後,才能返回FIN釋放連線報文。

所以是“三次握手”,“四次揮手”。

5.為什麼客戶端在TIME-WAIT階段要等2MSL?


為的是確認伺服器端是否收到客戶端發出的ACK確認報文

當客戶端發出最後的ACK確認報文時,並不能確定伺服器端能夠收到該段報文。所以客戶端在傳送完ACK確認報文之後,會設定一個時長為2MSL的計時器。MSL指的是Maximum Segment Lifetime:一段TCP報文在傳輸過程中的最大生命週期。2MSL即是伺服器端發出為FIN報文和客戶端發出的ACK確認報文所能保持有效的最大時長。

伺服器端在1MSL內沒有收到客戶端發出的ACK確認報文,就會再次向客戶端發出FIN報文;

  • 如果客戶端在2MSL內,再次收到了來自伺服器端的FIN報文,說明伺服器端由於各種原因沒有接收到客戶端發出的ACK確認報文。客戶端再次向伺服器端發出ACK確認報文,計時器重置,重新開始2MSL的計時;
  • 否則客戶端在2MSL內沒有再次收到來自伺服器端的FIN報文,說明伺服器端正常接收了ACK確認報文,客戶端可以進入CLOSED階段,完成“四次揮手”。

所以,客戶端要經歷時長為2SML的TIME-WAIT階段;這也是為什麼客戶端比伺服器端晚進入CLOSED階段的原因

6.抓包驗證


圖中顯示的就是完整的TCP連線釋放的”四次揮手”過程。在 80 -> 55389 中,假設80是本地(客戶端)埠,55389是伺服器埠。80埠與55389之間的四次來回就是"四次揮手"過程。

  • ”第一次揮手”客戶端傳送的FIN請求釋放連線報文以[FIN,ACK]作為標誌位,其中報文序號Seq=2445;確認號Ack=558;

注意:這裡與“第三次握手”的ACK並不是表示確認的ACK報文。

  • ”第二次揮手”伺服器端返回的ACK確認報文以[ACK]作為標誌位;其中報文序號Seq=558;確認號Ack=2246;

  • ”第三次揮手”伺服器端繼續返回的FIN同意釋放連線報文以[FIN,ACK]作為標誌位;其中報文序號Seq=558;確認號Ack=2246;

  • ”第四次揮手”客戶端發出的ACK確認接收報文以[ACK]作為標誌位;其中報文序號Seq=2446;確認號Ack=559;

後一次“揮手”傳輸報文中的序號Seq值等於前一次"握手"傳輸報文中的確認號Ack值;

後一次“揮手”傳輸報文中的確認號Ack值等於前一次"握手"傳輸報文中的序號Seq值;

故這是連續的“四次揮手”過程,與前面的分析相符。

參考資料:

TCP的三次握手與四次揮手理解及面試題(很全面)

深入淺出圖解【計算機網路】 之 【TCP可靠傳輸的實現: 三次握手+滑動視窗】

使用 WireShark 分析 TCP/IP 三次握手 和 四次揮手