《TCP三次捂手、四次揮手和狀態轉換詳解》

前言: 本文將講解TCP三次捂手建立連接,到四次揮手斷開連接的過程,並且配合TCP狀態轉換圖解釋。解釋SYN 、seq 、ack、FIN的含義和關係。建議讀者先理解三捂和四揮後在結合狀態轉換圖看,網絡編程面試經常會問道這個問題,建議讀者弄懂。

TCP三次捂手和四次揮手

三次捂手-麻垌小庫

名詞解釋

  • SYN: 請求建立連接
  • FIN:請求斷開連接
  • seq:序列號,如果是第一次發送,這個自己隨機產生,否則,在上一次基礎上 + 1。
  • ack:確認號,確認序列號是對方發送序列號 + 1,可以用來確認自己應答的是那個序列號的報文。
  • ESTABLISHED:此狀態表示已經建立連接,建立連接後的每次通信ACK都是client三次捂手最後發給server的確認號,直到FIN後。
  • TIME_WAIT:也成爲2MSL等待狀態,RFC 793 [Postel 1981c] 指出MSL爲2分鐘。然而,實現中的常用值是30s,60s,2min。

TCP狀態轉換圖

tcp狀態變遷-麻垌小庫

名詞解釋

一、下面是 TCP 三次握手過程的狀態變遷。請結合第一張三次握手過程圖理解:

  1. CLOSED: 起始點,在超時或者連接關閉時候進入此狀態,這並不是一個真正的狀態,而是這個狀態圖的假想起點和終點。
  2. LISTEN: 服務器端等待連接的狀態。服務器經過 socket,bind,listen
    函數之後進入此狀態,開始監聽客戶端發過來的連接請求。此稱爲應用程序被動打開(等到客戶端連接請求)。
  3. SYN_SENT: 第一次握手發生階段,客戶端發起連接。客戶端調用 connect,發送 SYN 給服務器端,然後進入 SYN_SENT
    狀態,等待服務器端確認(三次握手中的第二個報文)。如果服務器端不能連接,則直接進入CLOSED狀態。
  4. SYN_RCVD: 第二次握手發生階段,跟 3 對應,這裏是服務器端接收到了客戶端的 SYN,此時服務器由 LISTEN 進入
    SYN_RCVD狀態,同時服務器端迴應一個 ACK,然後再發送一個 SYN 即 SYN+ACK
    給客戶端。狀態圖中還描繪了這樣一種情況,當客戶端在發送 SYN 的同時也收到服務器端的
    SYN請求,即兩個同時發起連接請求,那麼客戶端就會從 SYN_SENT 轉換到 SYN_REVD 狀態。
  5. ESTABLISHED: 第三次握手發生階段,客戶端接收到服務器端的 ACK 包(ACK,SYN)之後,也會發送一個 ACK
    確認包,客戶端進入 ESTABLISHED 狀態,表明客戶端這邊已經準備好,但TCP
    需要兩端都準備好纔可以進行數據傳輸。服務器端收到客戶端的 ACK 之後會從 SYN_RCVD 狀態轉移到 ESTABLISHED
    狀態,表明服務器端也準備好進行數據傳輸了。這樣客戶端和服務器端都是 ESTABLISHED 狀態,就可以進行後面的數據傳輸了。
    所以ESTABLISHED 也可以說是一個數據傳送狀態。

二、下面看看TCP斷開ESTABLISHED的狀態變遷

被動斷開,即服務器主動發送FIN斷開連接狀態變遷如下:

  1. CLOSE_WAIT: 接收到服務器主動發送FIN之後,被動關閉的一方進入此狀態。具體動作是接收到 FIN,同時發送 ACK。之所以叫 CLOSE_WAIT可以理解爲被動關閉的一方此時正在等待上層應用程序發出關閉連接指令。前面已經說過,TCP關閉是全雙工過程,這裏客戶端執行了主動關閉,被動方服務器端接收到FIN後也需要調用 close 關閉,這個 CLOSE_WAIT 就是處於這個狀態,等待發送 FIN,發送了FIN 則進入 LAST_ACK狀態。
  2. LAST_ACK: 被動方(服務器端)發起關閉請求,由狀態2 進入此狀態,具體動作是發送 FIN給對方,同時在接收到ACK 時進入CLOSED狀態。

三、主動斷開客戶端主動發送FIN,即 TCP四次揮手過程的狀態變遷:

  1. FIN_WAIT_1: 第一次揮手。主動關閉的一方(執行主動關閉的一方既可以是客戶端,也可以是服務器端,這裏以客戶端執行主動關閉爲例),終止連接時,發送 FIN
    給對方,然後等待對方返回 ACK 。調用 close() 第一次揮手就進入此狀態。

  2. FIN_WAIT_2: 主動端(這裏是客戶端)先執行主動關閉發送FIN,然後接收到被動方返回的 ACK 後進入此狀態。

  3. CLOSING: 兩邊同時發起關閉請求時(即主動方發送FIN,等待被動方返回ACK,同時被動方也發送了FIN,主動方接收到了FIN之後,發送ACK給被動方),主動方會由FIN_WAIT_1
    進入此狀態,等待被動方返回ACK。

  4. TIME_WAIT: 從狀態變遷圖會看到,四次揮手操作最後都會經過這樣一個狀態然後進入CLOSED狀態。共有三個狀態會進入該狀態 由CLOSING進入:同時發起關閉情況下,當主動端接收到ACK後,進入此狀態,實際上這裏的同時是這樣的情況:客戶端發起關閉請求,發送FIN之後等待服務器端迴應ACK,但此時服務器端同時也發起關閉請求,也發送了FIN,並且被客戶端先於ACK接收到。
    由FIN_WAIT_1進入:發起關閉後,發送了FIN,等待ACK的時候,正好被動方(服務器端)也發起關閉請求,發送了FIN,這時客戶端接收到了先前ACK,也收到了對方的FIN,然後發送ACK(對對方FIN的迴應),與CLOSING進入的狀態不同的是接收到FIN和ACK的先後順序,由FIN_WAIT_2進入:這是不同時的情況,主動方在完成自身發起的主動關閉請求後,接收到了對方發送過來的FIN,然後迴應
    ACK。

TIME_WAIT存在的兩個理由

  • 可靠地實現TCP全雙工連接的終止;
  • 我們知道tcp是有超時重發機制的,TIME_WAIT允許老的重複分節(數據報)在網絡中消逝。

禁止轉載,拷貝請標明圖片出處。
參考:https://blog.csdn.net/wenqian1991/article/details/40110703

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