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)提供有關已接收的亂序位元組的信息,以促進快速重傳過程。