TCP 傳輸、重傳及工作原理

2023.10.19

TCP 傳輸、重傳及工作原理


TCP具有快速重傳功能- 在計時器到期之前重新傳輸遺失的段,為了允許快速重傳,我們需要為發送方和接收方設定一些規則。

IP和MAC層的記憶體受限,用於傳送封包。因此,它們都會限制訊息的長度。

這項限制要求TCP在提供給IP層之前,將可變長度的位元組打包成多個段。每個段的長度應該是適當的。

以下是一個簡單的圖示,展示了段是如何透過網路發送的。

1*IRdfZ4LKKpQ-KRz_Y3QR7g.png

客戶端的HTTP層正在向目標伺服器發送18位元組的流。

當位元組16-18尚未到達TCP層時,位元組12-15通過了它。TCP將它們打包成一個段,並附加了一個TCP頭,標記在黃色區域。

接下來,該段被IP層封裝,透過網路發送,然後到達伺服器。

假設TCP段的長度超過了底層支撐的長度。在這種情況下,IP層將負責將大段拆分成多個片段。這是一個昂貴的過程,因此我們希望避免這種情況。

但是TCP如何決定長度呢?這取決於最大段大小(MSS)。

理想情況下,我們希望選擇一個最大化資料量、最小化頭部比例並避免在IP層進一步拆分的MSS。

預設情況下,MSS為536位元組。這個數字是從哪裡來的呢?

  • IP的預設最大傳輸單元(MTU)為576位元組。超過此大小的任何內容都將被拆分。
  • IP頭佔用20位元組。
  • TCP頭佔用20位元組。

因此,536 = 576 - 20 - 20。

你可以看出MSS僅表示資料體的大小,不包括頭部。

1*creWLybyfKDBJgTzQP1kDg.png

MSS是在TCP三次握手期間進行協商的。以下是TCP段頭的格式。MSS位於TCP選項中。

1*pQpFRUuyzaG4JOm93Wg5Zw.png

在SYN訊息中,客戶端建議MSS為1460位元組。這被稱為發送方最大段大小(SMSS)。

1*dG1cCAjKY0v8Xfx2SeBcFA.png

在伺服器的回應中,它建議段的大小不超過1400位元組。由於大小來自伺服器,因此被稱為接收方最大段大小(RMSS)。

TCP 重傳

為了確保傳輸的可靠性,TCP需要完成兩個功能:

  • 當接收到訊息時,接收方向發送方發送確認(ACK)。
  • 當訊息遺失時,發送方重新傳輸訊息。

讓我們從一個簡單的模型開始。

1*bvkdWnFF55OCLfstaE_GEw.png

1.首先,發送方在發送訊息後維護一個計時器。2.在時間過期之前收到第一個ACK。然後,計時器被重置以等待第二個訊息,然後重複此過程。3.第二個計時器過期,沒有收到ACK。重傳開始。

這個簡單的設計是直接的,但效率較低,因為每個訊息都需要等待前一個ACK返回。

讓我們改進一下。

1*suv0nuvpmgUWaTd6riMUsQ.png

透過為每個訊息分配一個ID,我們可以迅速發送多個訊息。相同的ID與對應的計時器和ACK訊息相連結。

如果一則訊息遺失,例如#3,發送方將重新傳輸它。

在TCP中,「訊息ID」是什麼?它是序號。

1*EbU2NjtCGn8z4gVCJr2Tyg.png

這裡是一個訊息的範例:

  • 此TCP段的長度為647位元組。
  • 在此訊息之前,發送方已經發送了1461位元組。
  • 發送方將從2108開始發送更多位元組。

序號最多可以達到2³²。然後它會重新開始。

這帶來了一個問題。

1*RLp9kmWuRzlgY-NQs2F4Hw.png

想像一下,我們只有4個序號,每次發送1位元組。

  • 在過程中,第2個位元組(標記為#2)遺失。根據設計,#2將在以後的時間重新傳輸。
  • 我們繼續發送更多字節,直到序號從#1開始。此時,重新傳輸的#2被發送。
  • 接收方不知道這是舊的#2還是新的#2。這可能會搞亂事情。

為了解決這個問題,TCP選項中引入了時間戳記。

1*jSrwaU0L-2EHyyIxzb2w_A.png

時間戳可以消除具有相同序號的段之間的歧義。

讓我們將時間戳附加到每個段落。

接收方讀取時間戳B並將其與先前的時間戳記E進行比較,以確認這是一次重傳。否則,時間戳應該大於E。

TCP快速重傳

TCP具有快速重傳功能- 在計時器到期之前重新傳輸遺失的段。

為了允許快速重傳,我們需要為發送方和接收方設定一些規則。

  • 規則1:作為接收方,它應始終發送它期望接收的序號。例如,當接收方接收到段1時,它將回應ACK2,表示它期望在即將到來的訊息中接收段2。
  • 規則2:作為發送方,它應忽略計時器並在接收到3個重複的亂序ACK後立即開始重新傳輸遺失的段。

1*nbAE5D9yMkUxvxxR4PJ27g.png

上圖顯示了快速重傳的範例:

  • 在第一個2個段的傳輸之後,段3遺失。
  • 接收到段4時,接收方會依照規則發送ACK3,而不是ACK4。這是第一個重複的亂序ACK。
  • 再次,在接收到段5時,伺服器仍然期望重新傳輸段3。因此,第二個重複的ACK3被發送。
  • 然後,第三個重複的ACK3被發送。
  • 在這一刻,發送方進入快速重傳並重新傳輸段3。6.在接收到丟失的段後,接收方的ACK按順序返回,並期望在即將到來的消息中接收段7。
  • 但是存在一個問題- 發送方不知道段5和段6是否安全到達,直到快速重傳完成。如果兩個段都遺失,那麼後續的重傳將需要更長的時間。

接收方可以透過選擇性確認(SACK)功能與發送方共享訊息,以便促進重送過程。

TCP選用確認

1*GhT0tOhF3YGrgQOIY56Esw.png

SACK位於TCP選項中。

在SACK中,我們可以指定已經接收到的資料的範圍,超過確認號碼。

1*LujjJhnNyITz1dyL-CFfbA.png

這是SACK的範例,表示已接收的資料範圍從2872到3393。

有了它,發送方知道不需要重新傳輸這些邊界之間的任何位元組。

此外,發送方還可以找出其他遺失的段並儘快進行重傳。

總結

  • 最大段大小(MSS)定義了TCP段的長度。
  • 計時器幫助TCP重新傳輸遺失的段。
  • 在收到3個重複的ACK後,快速重傳在計時器到期前開始。
  • 選擇性確認(SACK)提供有關已接收的亂序位元組的信息,以促進快速重傳過程。