跳轉到內容

通訊網路/TCP 和 UDP 協議

來自華夏公益教科書,開放的書籍,開放的世界

TCP 和 UDP

[編輯 | 編輯原始碼]

TCP 和 UDP 協議是兩種不同的協議,它們處理 IP 網路(網際網路)中終端之間的資料通訊。本頁將討論什麼是 TCP 和 UDP,以及它們之間的區別。

在 OSI 模型中,TCP 和 UDP 是“傳輸層”協議。其中 TCP 是面向連線的協議,UDP 是無連線的協議。

面向連線與無連線

[編輯 | 編輯原始碼]

在經歷了模型的各個層級後,現在是時候看看 TCP 協議並研究其功能了。本節將幫助讀者瞭解 TCP 的概念和特性,然後逐步深入 TCP 的細節,如連線建立/關閉、TCP 中的通訊以及為什麼 TCP 協議被稱為可靠且自適應的協議。本節將以 UDP 和 TCP 的比較結束,並附上一個很好的練習,鼓勵讀者解決更多問題。

在撰寫本節之前,資訊已從各種來源學習,例如 TCP 指南、RFC、坦南鮑姆書籍和課堂筆記。

什麼是 TCP?

理論上,傳輸層協議可以是一個非常簡單的軟體例程,但 TCP 協議不能被稱為簡單。為什麼要使用像 TCP 一樣複雜的傳輸層?最重要的原因取決於 IP 的不可靠性。事實上,TCP 下面的所有層都是不可靠的,並且逐跳傳送資料報。IP 層逐跳傳送資料報,並不保證資料報的傳送;它是一個無連線的系統。IP 只處理資料報的路由;如果出現問題,IP 會毫不猶豫地丟棄資料包,並在過程中生成一條錯誤訊息返回給傳送方。確定透過網路傳送的資料報的狀態以及在部分資料報被丟棄時處理重新發送資訊的任務落在了 TCP 的肩上。

大多數使用者將 TCP 和 IP 視為緊密結合的一對,但 TCP 可以而且經常與其他傳輸協議一起使用。

例如,TCP 或其部分內容用於檔案傳輸協議 (FTP) 和簡單郵件傳輸協議 (SMTP),它們都不使用 IP。

傳輸控制協議為 IP 層和上層提供了大量的服務。最重要的是,它為上層提供了一個面向連線的協議,使應用程式能夠確保透過網路傳送的資料報完整無缺地接收。在這種情況下,TCP 充當訊息驗證協議,提供可靠的通訊。如果資料報損壞或丟失,通常是 TCP(而不是更高層中的應用程式)處理重新傳輸。

TCP 不是軟體。它是一個通訊協議。

TCP 管理來自更高層的 datagram 的流,以及來自 IP 層的傳入 datagram。它必須確保優先順序和安全性得到尊重。TCP 必須能夠處理上面某個應用程式的終止,該應用程式正在等待傳入 datagram,以及較低層中的故障。TCP 還必須維護一個狀態表,其中包含所有進出 TCP 層的資料流。將這些服務隔離在一個單獨的層中,使得應用程式可以在不考慮流控制或訊息可靠性的情況下進行設計。如果沒有 TCP 層,每個應用程式都必須自己實現這些服務,這將浪費資源。

TCP 位於傳輸層,位於 IP 之上,但位於上層及其應用程式之下,如下圖所示。TCP 僅駐留在實際處理 datagram 的裝置上,確保 datagram 已從源機器傳送到目標機器。它不駐留在僅路由 datagram 的裝置上,因此閘道器中沒有 TCP 層。這是有道理的,因為在閘道器上,資料報無需在分層模型中高於 IP 層。



圖 1:TCP 提供可靠的端到端通訊


因為 TCP 是一種面向連線的協議,負責確保資料報從源機器到目標機器的傳輸(端到端通訊),所以 TCP 必須接收來自目標機器的通訊訊息,以確認接收資料報。虛擬電路通常用於指代兩臺終端機器之間進行的握手,其中大多數是簡單的確認訊息(確認接收或故障程式碼)和資料報序列號。這類似於電話通話;某人透過撥打電話號碼來發起通話,該號碼被接聽,進行雙向通話,最後某人結束通話。套接字對標識連線的兩端,即虛擬電路。可以回憶起,套接字由 IP 地址和埠號組成,以標識位置。伺服器使用眾所周知的埠號(< 1000)來進行標準化服務(監聽)。1024 以上的號碼可供使用者自由使用。下表列出了一些標準服務的埠號。

一些標準服務的埠號
協議 用途
21 FTP 檔案傳輸
23 Telnet 遠端登入
25 SMTP 電子郵件
69 TFTP 簡單檔案傳輸協議
79 Finger 查詢有關使用者的資訊
80 HTTP 全球資訊網
110 POP-3 遠端電子郵件訪問
119 NNTP USENET 新聞


位元組流還是訊息流?

嗯,訊息邊界在 TCP 中不會端到端地保留。例如,如果傳送程序對 TCP 流執行了四次 512 位元組的寫入操作,這些資料可能會以四塊 512 位元組塊、兩塊 1024 位元組塊、一塊 2048 位元組塊,或其他方式交付給接收程序。接收方無法檢測到寫入資料的單位。TCP 實體接受來自本地程序的使用者資料流,將其分解成不超過 64 KB 的片段(實際上,通常為 1460 個數據位元組,以便放入具有 IP 和 TCP 頭部的單個乙太網幀),並將每個片段作為單獨的 IP 資料報傳送。當包含 TCP 資料的資料報到達機器時,它們會被傳遞給 TCP 實體,該實體會重建原始位元組流。為簡單起見,我們有時只使用*TCP* 來表示 TCP 傳輸實體(軟體)或 TCP 協議(一組規則)。從上下文中可以清楚地知道指的是哪個。例如,在*使用者將資料提供給 TCP* 中,顯然指的是 TCP 傳輸實體。IP 層不保證資料報能夠正確傳送,因此 TCP 必須按需超時並重新傳輸資料報。到達的資料報可能順序錯誤;TCP 還必須將它們按正確的順序重新組裝成訊息。簡而言之,TCP 必須提供大多數使用者想要而 IP 沒有提供的可靠性。


TCP 的特點

TCP 在每個主機系統上的程序之間提供了一個通訊通道。該通道可靠、全雙工且流式。為了實現此功能,TCP 驅動程式將會話資料流分解成離散的段,併為每個段附加一個 TCP 頭部。IP 頭部附加到此 TCP 資料包,然後將組合資料包傳遞到網路進行傳送。此 TCP 頭部包含許多欄位,用於支援預期的 TCP 功能。TCP 具有以下功能特性

單播協議:TCP 基於單播網路模型,支援恰好兩個方之間的資料交換。它不支援廣播或多播網路模型。

連線狀態:TCP 並不在網路內強制實施狀態來支援連線,而是使用兩個端點之間的同步狀態。此同步狀態是在初始連線過程中設定的,因此 TCP 可以被視為面向連線的協議。協議設計中的大部分內容旨在確保每個本地狀態轉換都被傳達給遠端方並得到遠端方的確認。


可靠性:可靠性意味著在連線一端傳遞給 TCP 驅動程式的位元組流將被傳輸到網路,以便位元組流以與傳送者生成的相同順序,相同的位元組序列呈現給遠端程序。這意味著協議會檢測資料流的哪些段被網路丟棄、重新排序、重複或損壞。必要時,傳送方將重新傳輸損壞的段,以便接收方能夠重建原始資料流。這意味著 TCP 傳送方必須保留所有已傳輸資料的本地副本,直到它收到指示接收方已完成對資料的準確傳輸的指示。


全雙工:TCP 是一種全雙工協議;它允許雙方在單個 TCP 連線的上下文中傳送和接收資料。


流式傳輸:雖然 TCP 使用資料包結構進行網路傳輸,但 TCP 是一個真正的流式傳輸協議,並且應用程式級網路操作並不透明。某些協議明確地封裝每個應用程式事務;對於每次寫入,都必須有一個匹配的讀取。以這種方式,應用程式派生的資料流到邏輯記錄結構的分割在網路上保留。TCP 不保留強加於資料流的這種隱式結構,因此網路協議中沒有寫入和讀取操作之間的配對。例如,TCP 應用程式可以將三個資料塊依次寫入網路連線,這些資料塊可以由遠端讀取器在一次讀取操作中收集。TCP 會話中使用的資料塊(段)的大小在會話開始時協商。傳送方嘗試在其允許的範圍內使用盡可能大的段大小來進行資料傳輸,這些範圍包括接收方的最大段大小、配置的傳送方的最大段大小以及網路路徑(路徑最大傳輸單元 [MTU])支援的最大非分段資料包大小。路徑 MTU 定期重新整理,以適應 TCP 連線處於活動狀態時網路中可能發生的任何更改。


速率自適應:TCP 也是一種速率自適應協議,因為資料傳輸速率旨在適應網路中普遍存在的負載條件並適應接收方的處理能力。沒有預定的 TCP 資料傳輸速率;如果網路和接收方都有額外的可用容量,則 TCP 傳送方將嘗試將更多資料注入網路,以佔用此可用空間。相反,如果出現擁塞,TCP 傳送方將降低其傳送速率以允許網路恢復。此自適應功能試圖在不觸發持續資料丟失的情況下實現儘可能高的資料傳輸速率。

TCP 報頭結構

[edit | edit source]

TCP 段作為 Internet 資料報傳送。Internet 協議報頭包含多個資訊欄位,包括源主機地址和目標主機地址。TCP 報頭緊隨 Internet 報頭,提供特定於 TCP 協議的資訊。這種劃分允許 TCP 以外的其他主機級別協議的存在。

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Source Port          |       Destination Port        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Sequence Number                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Acknowledgment Number                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Data |           |U|A|P|R|S|F|                               |
| Offset| Reserved  |R|C|S|S|Y|I|            Window             |
|       |           |G|K|H|T|N|N|                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           Checksum            |         Urgent Pointer        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Options                    |    Padding    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                             data                              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

                         TCP Header Format

       Note that one tick mark represents one bit position.

源埠:16 位 源埠號。

目標埠:16 位 目標埠號。

序列號:32 位 此段中第一個資料位元組的序列號(除非存在 SYN)。如果存在 SYN,則序列號是初始序列號 (ISN),第一個資料位元組是 ISN+1。

確認號:32 位 如果設定了 ACK 控制位,則此欄位包含段傳送方預期接收的下一個序列號的值。一旦建立連線,它就會始終被髮送。


資料偏移:4 位 TCP 報頭中的 32 位字數。這指示資料從何處開始。TCP 報頭(即使包含選項)也是 32 位的整數倍。


保留:6 位 為將來使用而保留。必須為零。


控制位:6 位(從左到右)

URG:緊急指標欄位有效

ACK:確認欄位有效

PSH:推送功能

RST:重置連線

SYN:同步序列號

FIN:傳送方沒有更多資料


視窗:16 位 從確認欄位中指示的第一個位元組開始,段傳送方願意接受的資料位元組數。


校驗和:16 位 校驗和欄位是報頭和文字中所有 16 位字的按位取反和的按位取反。如果段包含奇數個要進行校驗和的報頭和文字位元組,則最後一個位元組在右側用零填充以形成一個 16 位字,用於校驗和目的。填充不會作為段的一部分傳輸。在計算校驗和時,校驗和欄位本身將被替換為零。

校驗和還涵蓋一個 96 位偽報頭,該偽報頭概念上位於 TCP 報頭的前面。此偽報頭包含源地址、目標地址、協議和 TCP 長度。這使 TCP 免受錯誤路由段的攻擊。此資訊位於 Internet 協議中,並在 TCP/網路介面上的呼叫引數或結果中在 TCP 上傳輸。

TCP 長度是 TCP 報頭長度加上資料長度(以位元組為單位)(這不是顯式傳輸的量,而是計算出來的),它不包括偽報頭的 12 個位元組。


緊急指標:16 位 此欄位將緊急指標的當前值傳達為相對於此段中的序列號的正偏移量。緊急指標指向緊隨緊急資料的位元組的序列號。此欄位僅在設定了 URG 控制位的段中被解釋。


選項:可變 選項可能佔用 TCP 報頭末尾的空間,並且長度為 8 位的倍數。所有選項都包含在校驗和中。選項可以從任何位元組邊界開始。選項格式有兩種情況

情況 1:一個選項種類位元組。

情況 2:一個選項種類位元組、一個選項長度位元組以及實際的選項資料位元組。選項長度計算選項種類和選項長度這兩個位元組以及選項資料位元組。請注意,選項列表可能比資料偏移欄位暗示的要短。超過結束選項選項的報頭內容必須是報頭填充(即零)。


TCP 必須實現所有選項


Ethereal 捕獲

可以使用 Ethereal 捕獲檢視 TCP 資料包。下面捕獲了一個這樣的 TCP 資料包。請注意,ACK 標誌和 PUSH 標誌設定為“1”。

TCP 中的通訊

[edit | edit source]

在 TCP 可以用於任何實際有用的目的(即傳送資料)之前,必須在希望通訊的兩個裝置之間建立連線。此過程通常稱為連線建立,它涉及交換訊息,使兩個裝置從其初始連線狀態 (CLOSED) 轉變為正常操作狀態 (ESTABLISHED)。


連線建立功能


連線建立過程實際上在建立適合資料交換的連線時完成了以下幾件事

聯絡和通訊:客戶端和伺服器透過相互發送訊息來相互聯絡並建立通訊。在此之前,伺服器通常甚至不知道它將與哪個客戶端進行通訊,因此它是在連線建立期間發現這一點的。

序列號同步:每個裝置都讓另一個裝置知道它希望用於其第一次傳輸的初始序列號。

引數交換:兩個裝置交換控制 TCP 連線操作的某些引數。

用於連線建立的控制訊息:SYN 和 ACK

TCP 使用控制訊息來管理聯絡和通訊過程。但是,沒有特殊的 TCP 控制訊息型別;所有 TCP 訊息都使用相同的段格式。TCP 報頭中的一組控制標誌指示段是用於控制目的還是僅僅用於傳輸資料。在使用控制訊息時,以下標誌會發生變化。

SYN:此位表示段用於初始化連線。SYN 代表同步,指的是上面提到的序列號同步。

ACK:此位表示傳送段的裝置正在傳輸對其已接收的訊息(如 SYN)的確認。


正常的連線建立:“三次握手”


為了建立連線,每個裝置必須傳送 SYN 並從另一個裝置接收其 ACK。因此,從概念上講,需要在裝置之間傳遞四條控制訊息。但是,當可以同時通訊兩者時,在單獨的訊息中傳送 SYN 和 ACK 是低效的。因此,在連線建立的正常事件序列中,透過設定兩個相關位(一條訊息有時稱為 SYN+ACK),其中一個 SYN 和一個 ACK 會一起傳送。這樣總共需要三條訊息,因此該連線過程被稱為三次握手。

Key Concept:

The normal process of establishing a connection between a TCP client and 
server involves three steps:

客戶端傳送一個 SYN 訊息;伺服器傳送一條訊息,該訊息包含對客戶端 SYN 的 ACK 以及伺服器的 SYN;然後客戶端傳送對伺服器 SYN 的 ACK。這被稱為 TCP 三次握手。

連線在其生命週期中經過一系列狀態。

這些狀態是:LISTEN、SYN-SENT、SYN-RECEIVED、ESTABLISHED、FIN-WAIT-1、FIN-WAIT-2、CLOSE-WAIT、CLOSING、LAST-ACK、TIME-WAIT 和虛構狀態 CLOSED。CLOSED 是虛構的,因為它代表沒有 TCB,因此沒有連線的狀態。簡而言之,這些狀態的含義是

LISTEN - 代表等待來自任何遠端 TCP 和埠的連線請求。

SYN-SENT - 代表在傳送連線請求後等待匹配的連線請求。

SYN-RECEIVED - 代表在接收和傳送連線請求後等待確認的連線請求確認。

ESTABLISHED - 代表一個開放的連線,接收到的資料可以傳遞給使用者。連線資料傳輸階段的正常狀態。

FIN-WAIT-1 - 代表等待來自遠端 TCP 的連線終止請求,或先前傳送的連線終止請求的確認。

FIN-WAIT-2 - 代表等待來自遠端 TCP 的連線終止請求。

CLOSE-WAIT - 代表等待來自本地使用者的連線終止請求。

CLOSING - 代表等待來自遠端 TCP 的連線終止請求確認。

LAST-ACK - 代表等待先前傳送給遠端 TCP 的連線終止請求的確認(其中包括對其連線終止請求的確認)。

TIME-WAIT - 代表等待足夠的時間過去以確保遠端 TCP 收到了對其連線終止請求的確認。

CLOSED - 代表完全沒有連線狀態。

TCP 連線響應事件從一種狀態轉換到另一種狀態。這些事件是使用者呼叫、OPEN、SEND、RECEIVE、CLOSE、ABORT 和 STATUS;傳入的段,特別是那些包含 SYN、ACK、RST 和 FIN 標誌的段;以及超時。

圖 6 中的狀態圖僅說明狀態變化,以及導致的事件和產生的動作,但既不涉及錯誤條件,也不涉及與狀態變化無關的動作。在後面的部分,將提供更多關於 TCP 對事件反應的細節。


Key Concept:

If one device setting up a TCP connection sends a SYN and then receives a SYN
from the other one before its SYN is acknowledged, the two devices perform a
simultaneous open, which consists of the exchange of two independent SYN and
ACK message sets. The end result is the same as the conventional three-way
handshake, but the process of getting to the ESTABLISHED state is different. 
The possibility of collision normally occurs in Peer-2-Peer connection.


緩衝區管理 當傳送方(假設在我們這裡是指客戶端)要建立連線時,資料包會進入傳輸緩衝區。資料包應該附帶一些序列號。傳送方選擇序列號以儘量減少使用已使用序列號的風險。客戶端使用該序列號和資料以及資料包長度欄位傳送資料包。伺服器在收到資料包後,會發送下一個預期序列號的 ACK。它還會發送包含其自身序列號的 SYN。

客戶端在收到兩條訊息(SYN 和 ACK)後,會向接收方傳送 ACK,ACK 包含接收方下一個預期的序列號。因此,在客戶端和伺服器之間建立了序列號。現在,它們已準備好進行資料傳輸。即使在傳送資料時,也會遵循相同的序列號概念。


TCP 傳輸策略

TCP 中的視窗管理不像大多數資料鏈路協議那樣直接與確認相關聯。例如,假設接收方有一個 4096 位元組的緩衝區,如下圖所示。如果傳送方傳輸一個 2048 位元組的段,該段被正確接收,接收方將確認該段。但是,由於它現在只有 2048 位元組的緩衝區空間(直到應用程式從緩衝區中刪除一些資料),它將從下一個預期位元組開始宣佈 2048 的視窗大小。

現在傳送方傳輸另外 2048 位元組,這些位元組被確認,但宣佈的視窗大小為 0。傳送方必須停止,直到接收主機上的應用程式程序從緩衝區中刪除了一些資料,此時 TCP 可以宣佈一個更大的視窗大小。

當視窗大小為 0 時,傳送方通常不能傳送段,但有兩個例外。首先,可以傳送緊急資料,例如,允許使用者終止在遠端機器上執行的程序。其次,傳送方可以傳送一個 1 位元組的段,以使接收方重新宣佈下一個預期位元組和視窗大小。TCP 標準明確提供此選項以防止在視窗公告丟失時發生死鎖。

傳送方不需要在應用程式傳入資料時立即傳輸資料。接收方也不需要儘快傳送確認。當前 2 KB 的資料傳入時,TCP 知道它有一個 4 KB 的可用視窗,因此,只要將資料緩衝起來,直到另有 2 KB 的資料傳入,就可以完全正確地傳輸一個 4 KB 的有效載荷段。這種自由可以被利用來提高效能。

考慮一個與互動式編輯器建立的 telnet 連線,該編輯器對每個按鍵做出反應。在最壞的情況下,當一個字元到達傳送方的 TCP 實體時,TCP 建立一個 21 位元組的 TCP 段,它將其交給 IP 傳送為一個 41 位元組的 IP 資料報。在接收方,TCP 立即傳送一個 40 位元組的確認(20 位元組的 TCP 頭部和 20 位元組的 IP 頭部)。稍後,當編輯器讀取了該位元組時,TCP 傳送一個視窗更新,將視窗向右移動 1 個位元組。這個資料包也是 40 位元組。最後,當編輯器處理完該字元後,它將該字元作為 41 位元組的資料包進行回顯。總共使用了 162 位元組的頻寬,併為每個鍵入的字元傳送了四個段。當頻寬稀缺時,這種做事方式是不受歡迎的。

許多 TCP 實現使用的一種最佳化這種狀況的方法是將確認和視窗更新延遲 500 毫秒,以期獲得一些可以搭便車的自由資料。假設編輯器在 500 毫秒內進行回顯,現在只需要傳送一個 41 位元組的資料包回遠端使用者,從而將資料包數量和頻寬使用量減半。儘管此規則減少了接收方對網路造成的負載,但傳送方仍然透過傳送包含 1 位元組資料的 41 位元組資料包而低效地執行。一種減少這種使用的方法被稱為 Nagle 演算法(Nagle,1984)。Nagle 建議的方法很簡單:當資料以每次一個位元組的速度傳入傳送方時,只需傳送第一個位元組並緩衝其餘所有位元組,直到確認掛起的位元組。然後將所有緩衝的字元在一個 TCP 段中傳送,並開始再次緩衝,直到它們都被確認。如果使用者輸入速度很快,而網路速度很慢,則每個段中可能會有大量字元,從而大大減少了頻寬的使用量。該演算法還允許在有足夠的資料流入以填滿一半視窗或最大段時傳送新的資料包。

Nagle 演算法被 TCP 實現廣泛使用,但有時最好停用它。特別是,當透過網際網路執行 X 視窗應用程式時,必須將滑鼠移動傳送到遠端計算機。(X 視窗系統是大多數 UNIX 系統中使用的視窗系統。)將它們收集起來以突發形式傳送會導致滑鼠游標移動不穩定,從而使使用者感到不滿意。

另一個可能降低 TCP 效能的問題是愚蠢視窗綜合徵。當資料以大塊形式傳遞到傳送方的 TCP 實體,但接收方的一個互動式應用程式一次讀取 1 個位元組的資料時,就會出現此問題。要了解這個問題,請檢視下圖。最初,接收方上的 TCP 緩衝區已滿,並且傳送方知道這一點(即視窗大小為 0)。然後,互動式應用程式從 TCP 流中讀取一個字元。此操作使接收方的 TCP 很高興,因此它向傳送方傳送一個視窗更新,告訴它可以傳送 1 個位元組。傳送方照辦,傳送了 1 個位元組。緩衝區現在已滿,因此接收方確認 1 位元組段,但將視窗設定為 0。這種行為可以永遠持續下去。

Clark 的解決方案是阻止接收方傳送 1 位元組的視窗更新。相反,它被迫等待直到它有足夠的可用空間,然後才宣佈可用空間。具體來說,接收方不應該傳送視窗更新,直到它能夠處理在建立連線時宣佈的最大段大小,或者直到它的緩衝區為空一半,以較小者為準。

此外,傳送方也可以透過不傳送小段來提供幫助。相反,它應該嘗試等待直到它在視窗中累積了足夠的可用空間以傳送一個完整的段,或者至少傳送一個包含接收方緩衝區大小一半的段(它必須從過去收到的視窗更新模式中估計此值)。

Nagle 演算法和 Clark 對愚蠢視窗綜合徵的解決方案是互補的。Nagle 試圖解決傳送應用程式以每次一個位元組的速度將資料傳遞給 TCP 造成的問題。Clark 試圖解決接收應用程式以每次一個位元組的速度從 TCP 中吸取資料的問題。兩種解決方案都是有效的,可以協同工作。目標是讓傳送方不要傳送小段,接收方不要請求它們。

接收方的 TCP 可以進一步提高效能,而不僅僅是大塊地進行視窗更新。像傳送方的 TCP 一樣,它也可以緩衝資料,因此它可以阻塞來自應用程式的 READ 請求,直到它有大量資料可提供。這樣做減少了對 TCP 的呼叫次數,因此減少了開銷。當然,它也增加了響應時間,但對於非互動式應用程式(如檔案傳輸),效率可能比對單個請求的響應時間更重要。另一個接收方的問題是,如何處理亂序段。接收方可以自行決定保留或丟棄它們。當然,只有在接收了確認的位元組之前的所有資料時才能傳送確認。如果接收方收到段 0、1、2、4、5、6 和 7,它可以確認所有位元組,直到幷包括段 2 中的最後一個位元組。當傳送方超時時,它將重新傳輸段 3。如果接收方緩衝了段 4 到 7,則在收到段 3 後,它可以確認所有位元組,直到段 7 的末尾。

解釋示例:連線建立和終止

[編輯 | 編輯原始碼]

建立連線

只有在兩臺機器之間不存在套接字連線,並且兩臺機器都同意連線,並且兩臺機器都有足夠的 TCP 資源來為連線提供服務時,才能在兩臺機器之間建立連線。如果任何一個條件不滿足,則無法建立連線。連線的接受可以由應用程式或系統管理例程觸發。

當建立連線時,它將被賦予某些屬性,這些屬性在連線關閉之前有效。通常,這些將是優先順序值和安全值。當連線正在建立過程中時,這兩個應用程式會就這些設定達成一致。

在大多數情況下,兩個應用程式都期望建立連線,因此它們會發出主動或被動開啟請求。下圖顯示了 TCP 開啟的流程圖。該過程從機器 A 的 TCP 接收來自其 ULP 的連線請求開始,它會向機器 B 傳送一個主動開啟原語。構建的段將設定 SYN 標誌(設定為 1),並且將分配一個序列號。該圖用符號 SYN SEQ 50 表示,表示 SYN 標誌已開啟,序列號(初始傳送序列號或 ISS)為 50。(可以選擇任何數字。)

機器 B 上的應用程式將向其 TCP 發出被動開啟指令。當收到 SYN SEQ 50 段時,機器 B 的 TCP 將向機器 A 傳送一個確認,序列號為 51。機器 B 還將設定自己的初始傳送序列號。該圖將此訊息顯示為 ACK 51;SYN 200 表示該訊息是一個具有序列號 51 的確認,它已設定了 SYN 標誌,並且 ISS 為 200。

收到後,機器 A 會發送自己的確認訊息,並將其序列號設定為 201。這在圖中顯示為 ACK 201。然後,在開啟和確認連線後,機器 A 和機器 B 都透過 ULP 向請求應用程式傳送連線開啟訊息。

如前所述,遠端機器不需要發出被動開啟指令。在這種情況下,傳送機器將提供傳送和接收套接字號,以及優先順序、安全性和超時值。兩個應用程式同時請求主動開啟是常見的。這很容易解決,儘管它確實需要更多的網路流量。

資料傳輸

傳輸資訊很簡單,如下圖所示。對於機器 A 的 TCP 從 ULP 接收到的每個資料塊,TCP 會將其封裝並將其傳送到機器 B,並使用遞增的序列號。機器 B 接收到訊息後,將使用一個段確認來確認它,該確認會增加下一個序列號(因此表示它已接收所有直到該序列號的資料)。圖示顯示了僅傳輸了一個資訊段 - 每種方式一個。

TCP 資料傳輸服務實際上包含六種不同的子服務

全雙工:允許連線的兩端隨時傳輸,即使是同時傳輸。

及時性:使用計時器確保資料在合理的時間內傳輸。

有序:從一個應用程式傳送的資料將在另一端的接收順序相同。儘管資料報可能透過 IP 無序接收,但 TCP 會在將訊息傳遞到更高層之前按正確順序重新組裝訊息,從而實現這一點。

標記:所有連線都具有商定的優先順序和安全值。

流量控制:TCP 可以使用緩衝區和視窗限制來調節資訊流。

錯誤校正:校驗和確保資料沒有錯誤(在校驗和演算法的限制範圍內)。

關閉連線

要關閉連線,其中一個 TCP 會從 ULP 接收一個關閉原語,併發出一個設定了 FIN 標誌的訊息。這在圖 8 中顯示。在圖中,機器 A 的 TCP 使用下一個序列號將關閉連線的請求傳送到機器 B。然後,機器 B 會發送一個確認請求和其下一個序列號的確認。在此之後,機器 B 將透過其 ULP 將關閉訊息傳送到應用程式,並等待應用程式確認關閉。此步驟並非嚴格必要;TCP 可以無需應用程式批准就關閉連線,但一個行為良好的系統會通知應用程式狀態的變化。

在從應用程式收到關閉連線的批准後(或請求超時後),機器 B 的 TCP 會向機器 A 傳送一個帶有 FIN 標誌的段。最後,機器 A 確認關閉,連線終止。

當一方關閉套接字時,可能會突然終止連線。這可以在不通知另一臺機器的情況下完成,也不考慮兩臺機器之間傳輸的任何資訊。除了由於故障或電源中斷造成的突然關閉之外,使用者、應用程式或系統監控例程也可以啟動突然關閉,該例程認為連線值得終止。連線的另一端可能直到嘗試傳送訊息並且計時器超時時才會意識到突然終止已經發生。

為了跟蹤所有連線,TCP 使用一個連線表。每個現有連線在表中都有一個條目,顯示端到端連線的資訊。下面顯示了 TCP 連線表的佈局 -

每列的含義如下

狀態:連線的狀態(關閉、關閉中、偵聽、等待等)。

本地地址:連線的 IP 地址。處於偵聽狀態時,此值將設定為 0.0.0.0。

本地埠:本地埠號。

遠端地址:遠端的 IP 地址。

遠端埠:遠端連線的埠號。

TCP 重傳和超時

[編輯 | 編輯原始碼]

我們知道 TCP 提供了可靠的資料傳輸。但是,它如何知道何時重新傳輸已經傳輸的資料包。確實,接收者使用下一個預期的序列號來確認接收到的資料包。但是,如果傳送者沒有收到任何 ACK 會怎麼樣。

考慮以下兩種情況

未收到 ACK:在這種情況下,接收者確實會傳輸累積 ACK,但此幀在中途丟失。傳送者通常會在將傳送的資料包從其緩衝區中重新整理之前等待此累積 ACK。但為此,它必須開發一些機制,使傳送者可以在 ACK 持續很長時間未收到時採取一些措施。這裡用於此目的的機制是計時器。TCP 在傳輸資料包後立即設定一個計時器。如果在超時之前收到 ACK,則 TCP 會將這些資料包從其緩衝區中重新整理以騰出空間。如果在超時之前沒有收到 ACK,則在這種情況下,TCP 會再次重新傳輸資料包。但是,這個超時間隔是從哪裡選擇的。好吧,我們很快就會看到找出這個間隔的過程。

收到重複 ACK:在這種情況下,接收者會多次向傳送者傳送同一個資料包的 ACK。但是,有沒有想過為什麼會這樣?好吧,這些事情有時可能由於網路問題而發生,但是如果接收者確實收到 2-3 次以上的 ACK,那麼就有一些含義與這個問題相關聯。所有這些問題都從接收者端開始。接收者會一直向接收到的幀傳送 ACK。這個 ACK 具有累積性。這意味著接收者有一個緩衝區。用於傳送累積 ACK 的演算法可以取決於填充或剩餘的緩衝區量,或者它可能取決於計時器。通常,計時器被設定,以便在特定時間間隔後,接收者會發送累積 ACK。但是,如果傳送者的速率很高怎麼辦。在這種情況下,接收者緩衝區會填滿,之後它將失去儲存來自發送者端的任何更多資料包的能力。在這種情況下,接收者會繼續傳送重複的 ACK,這意味著緩衝區已滿,此後不再接受任何資料包。此訊息有助於傳送者控制流量速率。

整個過程使 TCP 成為一個自適應流量控制協議。這意味著在出現擁塞時,TCP 會調整其流量速率。更多內容將在擁塞控制主題中介紹。此外,TCP 中沒有負 ACK。上面的兩種情況向傳送者傳達了有關接收者狀態的正確訊息。現在讓我們關注 TCP 如何選擇超時間隔。

選擇超時間隔

計時器是根據資料包從傳送方到接收方完成往返所需的時間來選擇的。這種往返時間被稱為 RTT。但條件,即 RTT 並不總是保持不變。事實上,RTT 會隨時間發生很大的變化。因此,需要將一些平均量包含在超時間隔的計算中。以下是所遵循的過程。

1. 基於先前結果計算平均 RTT。(執行平均值)

2. 測量特定時間點的 RTT,此值取決於當時的網路狀況和擁塞。(測量值)

3. 計算超時間隔

                0.8*(Running avg. )  + (1- 0.8)*(Measured)

值 0.8 可以根據需要進行更改,但必須小於 1。

4. 為獲得更準確的結果,可以重複此過程多次。

因此,我們現在已經獲得了資料包完成往返所需的平均值。為了選擇超時間隔,需要將此值乘以某個因子,以建立一些餘量。

5. 因此,

超時間隔 = 2 * (步驟 4 中得到的數值)

如果我們繼續繪製執行平均值和特定時間的測量值的圖形,我們會發現執行平均值幾乎保持不變,而測量值則波動更大。以下是繪製的兩個值的圖形。這解釋了為什麼執行平均值要乘以一個大於用於乘以測量時間的數值的數值。

比較:TCP 和 UDP

[編輯 | 編輯原始碼]

使用者資料報協議 (UDP) 和傳輸控制協議 (TCP) 是 TCP/IP 協議套件中傳輸層的“兄弟”。它們執行相同的作用,在應用程式和網際網路協議 (IP) 的資料移動功能之間提供一個介面,但它們以截然不同的方式進行。因此,這兩種協議為更高層的協議提供了選擇,允許它們根據自己的需求選擇合適的協議。

下表有助於說明這兩種協議最基本的重要屬性及其對比。

練習題

[編輯 | 編輯原始碼]

這裡的練習題包括作業題及其解答。這將有助於學生掌握 TCP 的概念,並鼓勵他們從 Kurose 和 Tanenbaum 的書中尋找更多練習題。

1) UDP 和 TCP 使用 1 的補碼進行校驗和。假設您有以下三個 8 位位元組:01010101、01110000、01001100。這三個 8 位位元組之和的 1 的補碼是多少?(請注意,儘管 UDP 和 TCP 在計算校驗和時使用 16 位字,但對於此問題,您被要求考慮 8 位加數。)展示所有步驟。為什麼 UDP 會取和的 1 的補碼;也就是說,為什麼不直接使用和?在 1 的補碼方案中,接收方如何檢測錯誤?一個位元錯誤有可能不被檢測到嗎?兩個位元錯誤呢?

解答: 01010101 + 01110000 + 11000101 = 110001010

10001010 的 1 的補碼 = 校驗和 = 01110101。

在接收方,將 3 條訊息和校驗和加在一起以檢測錯誤。和始終應該只包含二進位制 1。如果和中包含 0 項,接收方就知道存在錯誤。接收方將檢測到 1 位錯誤。但對於 2 位錯誤並非總是如此,因為兩個不同的位可能會改變,但和可能仍然相同。


2) 回答以下問題的正確或錯誤,並簡要說明您的答案

a) 使用 SR 協議,傳送方有可能收到超出其當前視窗的報文的 ACK。

正確。考慮這樣一個場景:傳送方傳送的第一個資料包在計時器超時後沒有收到 ACK。因此它將再次傳送資料包。在此期間,收到第一個資料包的 ACK。因此傳送方清空其緩衝區並用新的資料包填充緩衝區。在此期間,可能會收到第二個幀的 ACK。因此,即使資料包超出當前視窗,也可能會收到 ACK。


b) 使用 GBN,傳送方有可能收到超出其當前視窗的報文的 ACK。

正確。對於 (a) 提供的相同論據也適用於這裡。


c) 交替位元協議與傳送方和接收方視窗大小為 1 的 SR 協議相同。

正確。交替位元協議將 0 和 1 視為交替的 ACK。這裡,累積 ACK 不可能,因為必須在收到每個資料包後傳送 ACK。因此,SR 協議開始表現得像交替位元協議。


d) 交替位元協議與傳送方和接收方視窗大小為 1 的 GBN 協議相同。

正確。相同的論據也適用於這裡。


3) 考慮 TCP 用於估計 RTT 的位置。假設 a=0.1,讓樣本 RTT1 為最近的樣本 RTT,讓樣本 RTT2 為次近的樣本 RTT,依此類推。

a) 對於給定的 TCP 連線,假設已返回四個確認,對應的樣本 RTT 為樣本 RTT4、樣本 RTT3、樣本 RTT2、樣本 RTT1。用四個樣本 RTT 表示估計的 RTT。

b) 針對 n 個樣本 RTT 推廣您的公式。

c) 對於 (b) 中的公式,讓 n 趨於無窮大。說明為什麼這種平均過程被稱為指數移動平均。

解答

a)

估計的 RTT1 = 樣本 RTT1

估計的 RTT2 = (1-a)估計的 RTT1 + a樣本 RTT2 = (1-a)樣本 RTT1 + a樣本 RTT2

估計的 RTT3 = (1-a)估計的 RTT2 + a樣本 RTT3 = (1-a)2樣本 RTT1 + (1-a)a樣本 RTT2 + a樣本 RTT3''

估計的 RTT4 = (1-a)估計的 RTT3 + a樣本 RTT4 = (1-a)3樣本 RTT1 + (1-a)2a樣本 RTT2 + (1-a)a樣本 RTT3 + a樣本 RTT4

b)

估計的 RTTn = (1-a)(n-1)樣本 RTT1 + (1-a)(n-2)a樣本 RTT2 + (1-a)(n-3)a樣本 RTT3 +... (1-a)a樣本 RTTn-1 + a樣本 RTTn


4) 我們從文字中瞭解到,TCP 必須收到三個重複的 ACK 才會執行快速重傳。您認為 TCP 設計人員為什麼選擇不在收到第一個重複的 ACK 後執行快速重傳?

解答:假設傳送方傳送 3 個連續的資料包 1、2 和 3。接收方收到 1 後,立即傳送其 ACK。假設由於重新排序,接收方收到 3 而不是 2。由於接收方沒有收到 2,因此它再次傳送 1 的 ACK。因此,傳送方收到了 1 的第二個 ACK。它仍然繼續等待。現在,當接收方收到 2 時,它傳送 ACK 2,然後傳送 3。因此,在重新傳輸資料包之前等待超過 2 個 ACK 始終是安全的。


5) 您認為為什麼 TCP 避免測量重新傳輸段的樣本 RTT?

解答:讓我們看看如果 TCP 測量重新傳輸段的樣本 RTT 會發生什麼問題。假設源傳送資料包 P1,P1 的計時器超時,然後源傳送 P2,即相同資料包的新副本。假設源測量 P2(重新傳輸的資料包)的樣本 RTT。最後假設在傳輸 P2 後不久,收到 P1 的確認。源將錯誤地將此確認視為 P2 的確認,並計算出不正確的樣本 RTT 值。

與 TCP 不同,UDP 不會在傳送資料之前建立連線,它只是傳送資料。因此,UDP 被稱為“無連線”。UDP 資料包通常被稱為“資料報”。DNS 服務是 UDP 執行的一個示例。DNS 伺服器使用 UDP 傳送和接收 DNS 請求。

在本節中,我們必須瞭解使用者資料報協議。它是一個傳輸層協議。本節將介紹 UDP 協議、其報頭結構以及它建立網路連線的方式。

如圖 1 所示,使用者資料報協議 (UDP) 是一個支援網路應用程式的傳輸層協議。它位於“會話”層之下,在開放式系統互聯模型 (OSI) 中位於 IP(網際網路協議)之上。該協議類似於 TCP(傳輸控制協議),後者用於視訊會議系統等客戶端/伺服器程式,但 UDP 是無連線的。

圖 1:OSI 層模型中的 UDP

什麼是 UDP?

[編輯 | 編輯原始碼]

'圖 2:UDP


UDP 是一個無連線且不可靠的傳輸協議。兩個埠用於識別源機器和目標機器中的端點。當不需要可靠的交付時,使用使用者資料報協議來代替 TCP。但是,UDP 從未使用於傳送重要的資料,例如網頁、資料庫資訊等。影片、音訊等流媒體使用 UDP,因為它速度快。

為什麼 UDP 比 TCP 更快?

UDP 比 TCP 更快的原因是它沒有流量控制。UDP 不進行任何錯誤檢查、錯誤校正或確認。UDP 只關注速度。因此,當透過網際網路傳送的資料受到衝突的影響時,就會存在錯誤。


UDP 資料包被稱為使用者資料報,具有 8 位元組的報頭。使用者資料報的格式如圖 3 所示。在使用者資料報中,前 8 個位元組包含報頭資訊,其餘位元組包含資料。

圖 3:UDP 資料報

源埠號:這是源主機使用的埠號,用於傳輸資料。它是一個 16 位長整數。因此,埠號的範圍在 0 到 65,535 之間。

目標埠號:這是目標主機使用的埠號,用於接收資料。它也是一個 16 位長整數,並且與源主機具有相同的埠號範圍。

長度:長度欄位是一個 16 位欄位。它包含使用者資料報、報頭和資料的總長度。

校驗和:UDP 校驗和是可選的。它用於檢測資料的錯誤。如果該欄位為零,則不計算校驗和。如果計算了真正的校驗和,則該欄位包含 1。

UDP 的特點

UDP 的特點如下。

• 端到端。UDP 可以識別執行在計算機上的特定程序。

• 不可靠的、無連線的傳遞(例如:美國郵政服務):

UDP 使用無連線的通訊設定。在這種情況下,UDP 不需要在傳送資料之前建立連線。通訊僅由資料段本身組成。

• 與 IP 相同的盡力而為語義

• 無確認、無排序、無流量控制

• 可能會丟失、重複、延遲、亂序或丟失連線

• 快速、低開銷

1. 適用於可靠的本地網路

2. RTP(即時傳輸協議)

通訊中的埠使用

[編輯 | 編輯原始碼]

在接收資料後,計算機必須有一些機制來處理它。假設使用者打開了三個應用程式,例如一個網頁瀏覽器、一個 Telnet 會話和一個 FTP 會話。這三個應用程式都透過網路傳輸資料。因此,應該有一些機制供作業系統確定哪些流量是針對哪個應用程式的。為了處理這種情況,使用了網路埠。可用的埠範圍是 0 到 65535。其中,0 到 1023 是眾所周知的埠,1023 到 49151 是註冊埠,而 49152 到 65535 是動態埠。


圖 4:埠

UDP 使用的眾所周知的埠列表

圖 5:UDP 使用的埠列表

UDP 報頭結構

[編輯 | 編輯原始碼]

它包含四個部分:源埠、目標埠、長度和校驗和。

圖 6:UDP 報頭

源埠

源埠是一個可選欄位。當使用時,它指示傳送程序的埠,並且在沒有其他資訊的情況下,可以假定為應將回復地址傳送到的埠。如果不使用,則插入值零。

目標埠

它是傳送資料的埠號。

長度

它包含 UDP 報頭和資料的長度。

該使用者資料報的長度(以八位位元組為單位),包括該報頭和資料。長度的最小值為八。

校驗和

校驗和的主要目的是錯誤檢測。它保證訊息到達正確的目的地。為了驗證校驗和,接收方必須從 IP 報頭中提取這些欄位。使用 12 位元組的偽報頭來計算校驗和。

資料

它是應用程式資料或實際訊息。


Ethereal 捕獲

可以使用 Ethereal 捕獲來檢視 UDP 資料包。下面捕獲並顯示了一個 UDP 資料包。

圖 7:Ethereal 捕獲

UDP 中的通訊

[編輯 | 編輯原始碼]

在 UDP 連線中,客戶端根據他們啟動連線的程式設定唯一的源埠號。UDP 不限於一對一互動。可以使用廣播或組播定址來提供一對多互動。可以使用多個客戶端與單個伺服器通訊來提供多對一互動。多對多互動只是這些技術的擴充套件。

UDP 校驗和和偽報頭

[編輯 | 編輯原始碼]

UDP 校驗和的主要目的是檢測傳輸段中的錯誤。

UDP 校驗和是可選的,但應始終開啟。

要計算 UDP 校驗和,需要將“偽報頭”新增到 UDP 報頭。偽報頭中的欄位都來自 IP 報頭。它們用於接收系統以確保 IP 資料報被正確的計算機接收。通常,偽報頭包含

圖 8:UDP 偽報頭

IP 源地址 4 位元組

IP 目標地址 4 位元組

協議 2 位元組

UDP 長度 2 位元組

校驗和計算

[編輯 | 編輯原始碼]

傳送方

1. 它將段內容視為 16 位整數的序列。

2. 將所有段加起來。我們稱之為 sum。

3. 校驗和:sum 的反碼。(在反碼中,所有 0 都轉換為 1,所有 1 都轉換為 0)。

4. 傳送方將此校驗和值放入 UDP 校驗和欄位中。

接收方

1. 計算校驗和

2. 將所有段加起來,然後將 sum 加上傳送方的校驗和。

3. 檢查校驗和中是否存在 0 位。如果接收方的校驗和包含任何 0,則檢測到錯誤。因此,資料包會被接收方丟棄。


這裡我們解釋了一個簡單的校驗和計算。例如,假設我們有位流 0110011001100110 0110011001100110 0000111100001111

該位流被分成 16 位整數段。

因此,它看起來像這樣

0110011001100110(16 位整數段)

0101010101010101

0000111100001111

第一個 16 位字的總和是

0110011001100110

0101010101010101


1011101110111011

將第三個字新增到上面的總和中得到

1011101110111011

0000111100001111


1100101011001010(所有段的總和)

現在要計算校驗和,取 sum 的反碼。如我之前提到的,反碼是透過將所有 1 轉換為 0,並將所有 0 轉換為 1 來實現的。因此,傳送方的校驗和是:0011010100110101。

現在在接收方,再次將所有段加起來。並將 sum 加上傳送方的校驗和。

如果沒有錯誤,接收方的檢查結果將是:1111111111111111。

如果報頭中存在任何 0 位,則校驗和存在錯誤。因此,資料包會被丟棄。

您可能想知道為什麼 UDP 在第一位提供校驗和,因為許多鏈路層協議(包括流行的乙太網協議)也提供錯誤檢查?原因是無法保證源和目的地之間的所有鏈路都提供錯誤檢查——其中一條鏈路可能使用不提供錯誤檢查的協議。由於 IP 應該在幾乎所有 2 層協議之上執行,因此傳輸層提供錯誤檢查作為安全措施非常有用。儘管 UDP 提供錯誤檢查,但它不會執行任何操作來從錯誤中恢復。UDP 的一些實現只是丟棄損壞的段;其他實現則將損壞的段連同警告一起傳遞給應用程式。

UDP 是一種傳輸層協議。UDP 是一種無連線的、不可靠的協議。UDP 不執行流量控制、錯誤控制或重傳錯誤段。UDP 比 TCP 快。UDP 通常用於流式音訊和影片。UDP 從未使用於重要文件,如網頁、資料庫資訊等。UDP 傳輸包含 8 位元組報頭的段。它包含源埠、目標埠、UDP 長度和校驗和。UDP 校驗和用於檢測傳輸段中的“錯誤”。

練習題

[編輯 | 編輯原始碼]

1. 計算以下序列的 UDP 校驗和:11100110011001101101010101010101。

答案:要計算校驗和,請按照以下步驟操作

       1. First of all divide the bit stream on to two parts of 16-bit each.
          The two bit streams will be  1110011001100110  and  1101010101010101.
      
       2. Add these two bit streams, so the addition will be: 
  
              1 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0
              1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
             ----------------------------------
            1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1  
              1 0 1 1 1 0 1 1 1 0 1 1 1 1 0 0   
                         
       3. Now apply one's complement to this bit stream. One's complement is achieved by converting all 1s into 0s and all 0s into 1s.
          So, the checksum will be : 0100010001000011.


2. 關閉校驗和欄位的優點是什麼?什麼時候適合關閉校驗和欄位?

答案

           By keeping checksum field turned off, this might save computational load and speed up data transfer.
           When we are transmitting data over wide area network(WAN), it is not a good idea to keep checksum off.
           We can keep checksum turned off when we are transmitting data over a Local Area Network(LAN),because switching infrastructure   
           would catch transmission error in the Ethernet protocol's checksum

簡介

當源傳送的資料包比目的地可以處理的資料包多時,就會發生擁塞。當發生這種擁塞時,效能會下降。當目的地端的這些緩衝區填滿時,就會發生擁塞。資料包通常會臨時儲存在源和目的地的緩衝區中,然後再轉發到它們的上一層。

什麼是擁塞?

假設我們正在觀察目的地。如果源傳送的資料包數量超過目的地緩衝區能夠處理的數量,就會發生擁塞。當發生擁塞時,目的地對於到達的資料包只有兩種選擇:丟棄或保留。如果目的地丟棄新到達的資料包並保留舊資料包,則此機制稱為“Y”模型。如果目的地丟棄舊資料包並用新資料包填充它們,則此機制稱為“牛奶”模型。在這兩種情況下,資料包都會被丟棄。檢測擁塞的兩種常見方法是超時和重複確認。

擁塞控制

擁塞控制可以用來計算傳送方可以傳送到網路上目的地的資料量。確定資料量並不容易,因為頻寬會隨著時間的推移而變化,連線會建立和斷開。根據這些因素,傳送方應該能夠調整流量。TCP 擁塞控制演算法用於檢測和控制擁塞。以下是我們將要討論的擁塞演算法。

  • 加性增加/乘性減少
  • 慢啟動
  • 擁塞避免
  • 快速重傳
  • 快速恢復

加性增加/乘性減少

此演算法用於網路的傳送方。擁塞視窗 SSIZE 是傳送方在收到 ACK 之前可以傳送到網路中的資料量。通告視窗 RSIZE 是接收方可以在網路上接收的資料量。TCP 源根據網路上的擁塞程度設定擁塞視窗。這是透過在擁塞增加時減少擁塞視窗,並在擁塞減少時增加擁塞視窗來完成的。這種機制通常被稱為加性增加/乘性減少。

源根據資料包丟失來確定擁塞。資料包丟失是在發生超時時確定的。源等待超時時間以確認到達。在正常情況下,資料包不會丟失,因此源假設發生超時時發生了擁塞。每當發生超時時,源都會將 SSIZE 設定為之前值的一半。這種機制稱為乘性減少。如果超時持續發生,視窗大小會一直減小,直到大小變為 1。這是因為擁塞視窗的最小值為 1。當傳送方確定沒有發生擁塞時,它會將擁塞視窗增加 1。這種增加在傳送方收到每個成功 ACK 後發生,如下所示。File:Congestion1.jpg

慢啟動

加性增加/乘性減少方法的主要缺點是,傳送方在檢測到擁塞時會將擁塞視窗減少一半,而對於每個成功接收的 ACK 則只增加 1。如果視窗大小很大或/和擁塞視窗大小從 1 增加,那麼我們會浪費很多擁塞視窗。慢啟動演算法用於解決這個問題。SSIZE 是傳送方在收到 ACK 之前可以傳送到網路中的資料量。RSIZE 是接收方可以在網路上接收的資料量。SSTHOLD 是慢啟動閾值,用於控制網路上的資料流量。當 SSIZE 小於閾值 SSTHOLD 時,使用慢啟動演算法。在開始時,傳送方不知道要傳送多少資料。它必須找到要傳送多少資料。最初,SSIZE 必須小於或等於 2*SMSS 位元組,並且不能超過 2 個段。隨著資料包的傳送,SSIZE 會呈指數級增長,直到 SSIZE 大於 SSTHOLD 或檢測到擁塞。


當傳送方檢測到擁塞時,它會將擁塞視窗減少一半。再次,慢啟動演算法用於增加擁塞視窗。

擁塞避免

SIZE 是傳送方在收到 ACK 之前可以傳送到網路中的資料量。RSIZE 是接收方可以在網路上接收的資料量。SSTHOLD 是慢啟動閾值,用於控制網路上的資料流量。當 SSIZE 大於閾值 SSTHOLD 時,使用擁塞避免演算法。隨著資料包的傳送,SSIZE 每往返時間增加一個完整大小的段。這會一直持續到檢測到擁塞。

快速重傳

以上三種演算法都使用超時來檢測擁塞。這裡的缺點是傳送方需要等待超時發生。為了改進擁塞檢測,傳送方使用重複 ACK。每次資料包到達接收方時,接收方都會向傳送方傳送 ACK。當資料包以亂序到達接收方時,TCP 無法立即確認資料包包含的資料,因為前面的資料包還沒有到達。接收方會發送上次傳送的同一個 ACK,導致重複 ACK。這在下面說明。

File:Congestion3.jpg

從傳送方的角度來看,重複 ACK 可能來自許多網路問題。傳送方不能假設傳送的資料包丟失,重複 ACK 可能由段重排序、ACK 複製或段複製觸發。因此,傳送方會等待 3 個重複 ACK 來確定資料包丟失。TCP 會重新傳輸看起來丟失的段,而不會等待重傳計時器過期。

快速恢復

快速恢復演算法控制新資料的傳輸,直到收到非重複 ACK。不執行慢啟動的原因是,收到重複 ACK 不僅表示一個段已丟失,還表示段很可能正在離開網路。快速重傳和快速恢復演算法通常一起實現,如下所示:1. 當收到第三個重複 ACK 時,將 STHOLD 設定為 STHOLD = max (FlightSize / 2, 2*SMSS),其中 FlightSize 是網路中未完成資料的數量。2. 重新傳輸丟失的段並將 SSIZE 設定為 STHOLD 加 3*SMSS。這會人為地“膨脹”擁塞視窗,膨脹的量等於已經離開網路並且接收方已經緩衝的段數(三個)。3. 對於收到的每個額外重複 ACK,將 SSIZE 增加 SMSS。這會人為地膨脹擁塞視窗,以反映已經離開網路的額外段。4. 傳輸一個段,如果新的 SSIZE 值和接收方通告的視窗允許的話。5. 當下一個確認新的資料的 ACK 到達時,將 SSIZE 設定為 STHOLD(在步驟 1 中設定的值)。這被稱為“縮小”視窗。此 ACK 應該是由步驟 1 中的重傳引起的確認,在重傳後一個 RTT 到達(雖然在接收方資料段存在顯著亂序傳遞的情況下,它可能會更早到達)。此外,此 ACK 應該確認在丟失段和收到第三個重複 ACK 之間傳送的所有中間段,如果這些段都沒有丟失。

常見問題解答

什麼會導致擁塞?當源傳送的資料包數量超過目的地能夠處理的數量時,就會發生擁塞。當發生這種擁塞時,效能會下降。當這些緩衝區在目的地側被填滿時,就會發生擁塞。資料包通常會暫時儲存在源和目的地的緩衝區中,然後再轉發到它們的上層。假設我們正在觀察目的地。如果源傳送的資料包數量超過目的地緩衝區能夠處理的數量,就會發生擁塞。

當發生擁塞時會發生什麼?當發生擁塞時,目的地對於到達的資料包只有兩種選擇:丟棄或保留。如果目的地丟棄新到達的資料包並保留舊資料包,則此機制稱為“Y”模型。如果目的地丟棄舊資料包並用新資料包填充它們,則此機制稱為“牛奶”模型。在這兩種情況下,資料包都會被丟棄。

如何檢測擁塞?檢測擁塞的兩種常見方法是超時和重複確認。

華夏公益教科書