TCP 狀態轉移圖?
TCP 狀態轉移圖 ?
上半部分是TCP三路握手過程的狀態變遷,下半部分是TCP四次揮手過程的狀態變遷。
CLOSED:起始點,在超時或者連線關閉時候進入此狀態,這並不是一個真正的狀態,而是這個狀態圖的假想起點和終點。
LISTEN:伺服器端等待連線的狀態。伺服器經過 socket,bind,listen 函式之後進入此狀態,開始監聽客戶端發過來的連線請求。此稱為應用程式被動開啟(等到客戶端連線請求)。
SYN_SENT:第一次握手發生階段,客戶端發起連線。客戶端呼叫 connect,傳送 SYN 給伺服器端,然後進入 SYN_SENT 狀態,等待伺服器端確認(三次握手中的第二個報文)。如果伺服器端不能連線,則直接進入CLOSED狀態。
SYN_RCVD:第二次握手發生階段,跟 3 對應,這裡是伺服器端接收到了客戶端的 SYN,此時伺服器由 LISTEN 進入
SYN_RCVD狀態,同時伺服器端迴應一個 ACK,然後再發送一個 SYN 即 SYN+ACK 給客戶端。狀態圖中還描繪了這樣一種情況,當客戶端在傳送 SYN 的同時也收到伺服器端的 SYN請求,即兩個同時發起連線請求,那麼客戶端就會從 SYN_SENT 轉換到 SYN_REVD 狀態。
ESTABLISHED:第三次握手發生階段,客戶端接收到伺服器端的 ACK 包(ACK,SYN)之後,也會發送一個 ACK 確認包,客戶端進入 ESTABLISHED 狀態,表明客戶端這邊已經準備好,但TCP 需要兩端都準備好才可以進行資料傳輸。伺服器端收到客戶端的 ACK 之後會從 SYN_RCVD 狀態轉移到 ESTABLISHED 狀態,表明伺服器端也準備好進行資料傳輸了。這樣客戶端和伺服器端都是 ESTABLISHED 狀態,就可以進行後面的資料傳輸了。所以 ESTABLISHED 也可以說是一個數據傳送狀態。
上面就是 TCP 三次握手過程的狀態變遷。從報文的角度看狀態變遷:SYN_SENT 狀態表示已經客戶端已經發送了 SYN 報文,SYN_RCVD 狀態表示伺服器端已經接收到了 SYN 報文。
下面看看TCP四次揮手過程的狀態變遷。結合第一張四次揮手過程圖來理解。
FIN_WAIT_1:第一次揮手。主動關閉的一方(執行主動關閉的一方既可以是客戶端,也可以是伺服器端,這裡以客戶端執行主動關閉為例),終止連線時,傳送 FIN 給對方,然後等待對方返回 ACK 。呼叫 close() 第一次揮手就進入此狀態。
CLOSE_WAIT:接收到FIN 之後,被動關閉的一方進入此狀態。具體動作是接收到 FIN,同時傳送 ACK。之所以叫
CLOSE_WAIT: 可以理解為被動關閉的一方此時正在等待上層應用程式發出關閉連線指令。前面已經說過,TCP關閉是全雙工過程,這裡客戶端執行了主動關閉,被動方伺服器端接收到FIN 後也需要呼叫 close 關閉,這個 CLOSE_WAIT 就是處於這個狀態,等待發送 FIN,傳送了FIN 則進入 LAST_ACK 狀態。
FIN_WAIT_2:主動端(這裡是客戶端)先執行主動關閉傳送FIN,然後接收到被動方返回的 ACK 後進入此狀態。
LAST_ACK:被動方(伺服器端)發起關閉請求,由狀態2 進入此狀態,具體動作是傳送 FIN給對方,同時在接收到ACK 時進入CLOSED狀態。
CLOSING:兩邊同時發起關閉請求時(即主動方傳送FIN,等待被動方返回ACK,同時被動方也傳送了FIN,主動方接收到了FIN之後,傳送ACK給被動方),主動方會由FIN_WAIT_1 進入此狀態,等待被動方返回ACK。
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。