TCP 連線管理

言技發表於2018-12-13

概述

  TCP是面向連線的協議。運輸連線是用來傳輸報文的。運輸連線的建立和釋放在每一次通訊中是必不可少的內容。因此運輸連線分為三個階段:建立連線、傳輸資料和釋放連結。運輸管理就是保證每一步都能正常執行。

在TCP 連線的建立過程主要解決三個問題:

  1. 要使每一方都能夠知道對方的存在
  2. 要允許雙方協商一些引數(如視窗最大值、是否使用視窗擴大選項和時間戳等)
  3. 能夠對運輸實體資源(如快取大小、連線表中的專案等)進行分配。

一、TCP 連線的建立

在這裡插入圖片描述

TCP 的連線建立,我們常常稱為三次握手。

A:您好,我是A。

B:您好,我是B

A:您好B。

連線過程

假設A 為客戶端(上圖左),B 為服務端(右)

  1. 一開始A、B 均為關閉狀態。B先開啟伺服器,建立傳輸控制塊TCB。準備接受連線請求,然後處於LISTEN 狀態。等待使用者連線請求並作出響應。

TCB:(Transmission Control Block,儲存了每一個連線中的一些重要資訊,如:TCP 連線表,指向傳送和接受快取的指標,指向重傳佇列的指標,當前傳送和接受序號等等)

  1. A 也是先建立連線控制模組TCB 。然後A 向B 傳送請求報文段,這時首部中的同部位SYN = 1,同時選擇一個初始序號 seq = x。TCP 規定,SYN 報文段不能攜帶資料,但要消耗掉一個序號。然後客戶端進入SYN-SEND (同步已傳送)狀態。
  2. B 接受到A 的連線請求後,如果同意連線需要給S 傳送確認。確認報文段ACK 置為1,確認號ack = x+1,同時選擇一個自己的初始序號seq = y。請注意這個報文段也不能傳輸資料,但也要消耗一個序號。這是B 進入SYN-RCVD (同步收到)狀態。
  3. A 收到B 的確認後,需要傳送一個確認給B。確認報文段ACK 置為1,確認號ack = y + 1,而自己的序號seq = x + 1,。TCP 規定,ACk 報文段可以新增資料。但如果沒有新增資料則不消耗序號。這時,TCP 連線已經建立,A 進入ESTABLISHED (已經建立連線)狀態。
  4. B 收到 A 的確認也進入ESTABLISHED (已經建立連線)狀態。

為什麼TCP 是三次握手?

假設A B 只用兩次握手就建立連線。

當A 第一次傳送給B 連線請求時,如果遲遲得不到迴應,A會再次傳送連線請求。那麼現在網路中有兩次請求,一般情況下第一次請求掛掉了,那麼B 收到第二次請求,然後迴應A,連線建立,沒毛病。但是第一次請求可能只是滯後了,假設AB斷開連線後,B 又收到了第一次請求,又會嘗試建立連線,但是A 會覺得自己沒有嘗試建立連線,從而拒絕B。因為是兩次握手,B 會以為自己已經建立連線了,等待A 傳送資料,白白浪費資源。

三次握手就不會出現這個問題,B 在傳送確認後,得不到A 的確認,就會知道這是個過時的請求,知道A 沒有要求建立連線。

二、TCP 連線釋放

在這裡插入圖片描述
好了,說完了連線,接下來說一說“拜拜”,好說好散。這常被稱為四次揮手。

A:B 啊,我不想玩了。

B:哦,你不想玩了啊,我知道了。

這個時候,還只是 A 不想玩了,也即 A 不會再傳送資料,但是 B 能不能在 ACK 的時候,直接關閉呢?當然不可以了,,很有可能 A 是發完了最後的資料就準備不玩了,但是 B 還沒做完自己的事情,還是可以傳送資料的,所以稱為半關閉的狀態。

這個時候 A 等待 B 也主動關閉。

B:A 啊,好吧,我也不玩了,拜拜。

A:好的,拜拜。

釋放連結的過程

首先AB 都處於ESTABLISHED 狀態

  1. A 先傳送連線釋放報文段,並停止傳送資料,主動關閉TCP 連線。A 把連結釋放報文段首部的中止控制位FIN 置為1 ,其序號為seq = u(等於前一個傳輸資料的序號+1)。這是A 進入 FIN-WAIT-1(終止等待連線1)狀態,等待B 的確認。TCP規定,FIN 報文段即使不攜帶資料,也會消耗一個序號。
  2. B 收到A 的連線釋放報文段後發出確認。確認號ack = u + 1,而報文段自己的序號seq = v(等於前一個傳輸資料的序號+1)。然後B 進入CLOSED-WAIT(關閉等待)狀態,這是A->B方向的連線就已經斷開了,TCP 連線處於半關閉狀態.
  3. A 收到B 的確認後,進入FIN-WAIT-2(終止等待2)狀態,等待B 傳送釋放報文段。
  4. 若B 傳送完資料後,向A 傳送TCP 釋放報文段。FIN 置為1 ,先假設序號seq = w (B可能又傳送了一些資料),B 還必須重複上次已經傳送的確認號ack = u + 1。這是B 進入LAST-ACK(最後確認)狀態,等待A 的確認
  5. A 在收到連線釋放報文段後傳送確認。在確認報文段中把ACK 置為1 ,確認號ack = w + 1,而自己的序號seq = u + 1(TCP 規定,前面傳送過的FIN 報文段要消耗一個序號)。然後進入到TIME-WAIT(時間等待)狀態
  6. 現在TCP 連線還沒有斷掉。必須經過時間等待計時器(TIME-WAIT time)設定的2MSL時間過後,A 才進入到CLOSED 狀態。

MSL(Maximum Segment Lifetimr)最長報文生存時間,RFC793 建議為2 分鐘。

  1. B 收到A 的ACK 後進入CLOSED 狀態

為什麼A 在TIME-WAIT 必須等待2MSL時間?

  1. 為了保證A 傳送的最後一個ACK 報文段能夠到達B。
  2. 防止已失效的連線請求報文段出現在本連結中。A 在傳送完最後一個ACK 後,在經過2MSL 的等待時間可以保證本連結持續時間內傳送的報文在網路中消失。這樣就不會出現舊連線請求出現在新連線請求裡面的情況

TCP 保活計時器

除了時間等待器外,TCP 還設有一個保活計時器(keepalive timer)。

當客戶與伺服器建立了連線,而客戶出現故障無法響應客戶端時,伺服器就會發一個探測報文,75秒發一個,若連續發10 個客戶端都沒響應,則伺服器端自動關閉連線。保活計時器預設為2 個小時,每收到一次請求重新整理。

TCP 狀態機

在這裡插入圖片描述

參考資料

  • 極客時間:《趣談網路協議》
  • 《計算機網路》

相關文章