TCP 傳輸、重傳及工作原理

IP 和 MAC 層的內存受限,用於發送數據包。因此,它們都會限制消息的長度。

這一限制要求 TCP 在提供給 IP 層之前,將可變長度的字節打包成多個段。每個段的長度應該是合適的。

下面是一個簡單的圖示,展示了段是如何通過互聯網發送的。

客戶端的 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 僅表示數據體的大小,不包括頭部。

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

在 SYN 消息中,客戶端建議 MSS 爲 1460 字節。這被稱爲發送方最大段大小(SMSS)

在服務器的響應中,它建議段的大小不超過 1400 字節。由於大小來自服務器,因此被稱爲接收方最大段大小(RMSS)

TCP 重傳

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

  1. 當接收到消息時,接收方向發送方發送確認(ACK)。2. 當消息丟失時,發送方重新傳輸消息。

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

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

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

讓我們改進一下。

通過爲每條消息分配一個 ID,我們可以迅速發送多條消息。相同的 ID 與相應的計時器和 ACK 消息相鏈接。

如果一條消息丟失,例如 #3,發送方將重新傳輸它。

在 TCP 中,“消息 ID” 是什麼?它是序列號

這裏是一個消息的示例。

• 此 TCP 段的長度爲 647 字節。• 在此消息之前,發送方已經發送了 1461 字節。• 發送方將從 2108 開始發送更多字節。

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

這帶來了一個問題。

想象一下,我們只有 4 個序列號,每次發送 1 字節。

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

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

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

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

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

TCP 快速重傳

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

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

規則 1:作爲接收方,它應始終發送它期望接收的序列號。

例如,當接收方接收到段 1 時,它將響應 ACK2,表示它期望在即將到來的消息中接收段 2。

規則 2:作爲發送方,它應忽略計時器並在接收到 3 個重複的亂序 ACK 後立即開始重新傳輸丟失的段。

上圖顯示了快速重傳的示例。

  1. 在第一個 2 個段的傳輸之後,段 3 丟失。2. 在接收到段 4 時,接收方根據規則發送 ACK3,而不是 ACK4。這是第一個重複的亂序 ACK。3. 再次,在接收到段 5 時,服務器仍然期望重新傳輸段 3。因此,第二個重複的 ACK3 被髮送。4. 然後,第三個重複的 ACK3 被髮送。5. 在這一刻,發送方進入快速重傳並重新傳輸段 3。6. 在接收到丟失的段後,接收方的 ACK 按順序返回,並期望在即將到來的消息中接收段 7。

但是存在一個問題 - 發送方不知道段 5 和段 6 是否安全到達,直到快速重傳完成。如果兩個段都丟失,那麼後續的重傳將需要更長的時間。

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

TCP 選擇性確認

SACK 位於 TCP 選項中。

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

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

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

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

總結

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

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