【網絡協議】精講 TCP 狀態機!圖解超讚超詳細!!!

大家好,我是 風雲說通信 ,深耕無線通信網絡協議領域:

今天我們來學習下 TCP 狀態機

1. TCP 狀態機是 TCP 連接的變化過程

     Tcp 在三次握手和四次揮手的過程,就是一個 tcp 的狀態說明,由於 tcp 是一個面向連接的,可靠的傳輸,每一次的傳輸都會經歷連接,傳輸,關閉的過程,無論是哪個方向的傳輸,必須建立連接纔行,在雙方通信的過程中,tcp 的狀態是不一樣的。

       下面介紹一下,在三次握手和四次揮手的過程中的幾種狀態,如下圖所示,是 tcp 狀態的變化過程:

TCP 的 11 種狀態:

CLOSED: 初始時沒有任何連接的狀態。

LISTEN: 服務器監聽來自客戶端的連接請求 (SYN 包)。

SYN_SENT: 客戶端 socket 執行 CONNECT 連接,發送 SYN 包,之後等待來自服務器的 SYN ACK 包 (服務器的連接請求和對客戶端連接請求的確認)。

SYN_RCVD: 服務端收到客戶端的 SYN 包併發送服務端 SYN ACK 包,之後等待客戶端對連接請求的確認 (ACK 包)。

ESTABLISH: 表示連接建立。客戶端發送了最後一個 ACK 包後進入此狀態,服務端接收到 ACK 包後進入此狀態。

FIN_WAIT_1: 終止連接的一方(通常是客戶機)發送了 FIN 包後進入此狀態,之後等待對方 FIN 包。

CLOSE_WAIT: (假設服務器)接收到客戶機 FIN 包之後等待關閉的階段。在接收到對方的 FIN 包之後,自然是需要立即回覆 ACK 包的,表示已經知道斷開請求。但是本方是否立即斷開連接(發送 FIN 包)取決於是否還有數據需要發送給客戶端,若還有數據要發送,則在發送 FIN 包之前均爲此狀態。

FIN_WAIT_2: 客戶端接收到服務器的 ACK 包,但並沒有立即接收到服務端的 FIN 包,進入 FIN_WAIT_2 狀態。此時是半連接狀態,即有一方要求關閉連接,等待另一方關閉。

LAST_ACK: 服務端發動最後的 FIN 包,等待最後的客戶端 ACK 包。

CLOSING: 當主動關閉方處於 FIN_WAIT_1 時,被動關閉方的 FIN 先於之前的自己發送的 ACK 到達,主動關閉方就直接 FIN_WAIT_1 -> CLOSING,(其實就相當於同時關閉),然後遲來的 ACK 到達時,主動關閉方就從 CLOSING -> TIME_WAIT。

TIME_WAIT: 客戶端收到服務端的 FIN 包,並立即發出 ACK 包做最後的確認,在此之後的 2MSL(兩倍的最長報文段壽命) 時間稱爲 TIME_WAIT 狀態

2. 正常狀態變遷

服務端正常狀態變遷:

  1. 服務器通過 listen() 系統調用後進入 LISTEN 狀態,被動等待客戶端連接 (被動打開)。

  2. 服務器一旦監聽到某個連接請求 (收到同步報文段 SYN),就將該連接放入內核請求等待隊列中,並向客戶端發送 SYN ACK 同步確認報文段,此時服務端處於 SYN_RCVD 狀態,等待客戶端的確認。

  3. 服務器成功接收到客戶端發送回的 ACK 確認報文段後,進入 ESTABLISHED 狀態。(此時已建立連接,雙方能夠進行雙向數據傳輸)

  4. 數據傳輸完畢,服務器收到客戶端發送的 FIN 結束報文段後,給客戶端發送回 ACK 確認報文段 (服務器可能還有數據要發),此時服務端處於 CLOSE_WAIT 狀態,服務器繼續發送未發完的數據。

  5. 服務器在發送完數據後給客戶端發送 FIN 結束報文段,之後進入 LAST_ACK 狀態,等待客戶端對結束報文段的最後一次確認。

  6. 服務器成功收到客戶端發送回的 ACK 確認報文段後,連接徹底關閉,進入 CLOSE 狀態。

客戶端正常狀態變遷:

  1. 客戶端通過 connect() 系統調用給服務器發送一個 SYN 同步報文段請求建立連接,此時客戶端進入 SYN_SENT 狀態。

  2. 客戶端成功收到服務器發送回的 SYN ACK 同步確認報文段後,再給服務器發送一個 ACK 確認報文段,之後進入 ESTABLISHED 狀態。(此時已建立連接,雙方能夠進行雙向數據傳輸)

  3. 數據傳輸完畢後,客戶端給服務器發送一個 FIN 結束報文段,之後進入 FIN_WAIT_1 狀態,等待服務端的確認。

  4. 客戶端收到服務器發送的 ACK 確認報文段後,進入 FIN_WAIT_2 狀態,之後接收服務器發送的還未發完的數據。

  5. 服務器發完數據後,客戶端收到服務器發送的 FIN 結束報文段,同時給服務端發回一個 ACK 確認報文段,之後進入 TIME_WAIT 狀態。

  6. TIME_WAIT 狀態下等待 2MSL 時長內,如果客戶端沒有收到服務器重傳的 FIN 結束報文段,則連接徹底關閉,此時進入 CLOSE 狀態。

下圖是時序圖

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/291r320lazaRoyQ-SaRylw