【計算機網路筆記】3.3 Connectionless Transport: UDP

Hello Guys, I’m LukeTseng. 歡迎你也感謝你點入本篇文章,本系列主要讀本為《Computer Networking: A Top-Down Approach, 8th Edition》,就是計算機網路的聖經,會製作該系列也主要因為修課上會用到。若你喜歡本系列或本文,不妨動動你的手指,為這篇文章按下一顆愛心吧,或是追蹤我的個人公開頁也 Ok。

回顧 UDP

UDP(User Datagram Protocol,使用者資料包協定)只做了傳輸層最基本該做的事:把資料從一台電腦的某個程式,送到另一台電腦的某個程式,其他的它一概不管。

雖然 TCP 提供了可靠、有序的傳輸,但這些功能是有代價的(延遲、複雜度、連線建立時間)。

有些應用程式(如 DNS 查詢、即時語音、串流視訊)更在乎「速度」和「即時性」,對於偶爾掉幾個封包是可以容忍的,此時 TCP 的層層機制反而成了累贅,輕量級的 UDP 就派上用場了。

UDP 應用:即時影音串流、網路電話(VoIP,Voice over Internet Protocol)、DNS 查詢、網路管理(SNMP,Simple Network Management Protocol),以及現代新型傳輸協定(如 HTTP/3 的底層 QUIC,Quick UDP Internet Connections)。

UDP 到底做了什麼?

如果選擇使用 UDP,則其應用程式幾乎是直接與 IP 層(網路層)打交道。

UDP 只在 IP 的基礎上增加了兩樣極少的東西:

  1. 多工/解多工(Multiplexing/Demultiplexing):透過埠號(Port number)區分不同的應用程式。
  2. 輕量的錯誤檢查:透過檢查和(Checksum)簡單確認資料有沒有壞掉。

UDP 不保證資料會送達,也不保證資料的順序,若網路塞車,路由器會丟棄封包,UDP 發送端不會知道,也不會重傳。

為什麼有些應用程式偏愛 UDP 而非 TCP?

共有四大理由:

  1. 控制權(Application-level control):
    • UDP 優勢:更精細的控制發送時間與內容。
    • 說明:
      • TCP 會受到擁塞控制(Congestion Control)的限制,網路塞車時會強制慢下來,且會一直重傳直到對方收到。
      • 對於即時應用很不利,而用 UDP,應用程式想送就送,雖然可能會掉封包,但這對即時通話來說,比畫面卡住等重傳好多了。
  2. 連線建立方面:
    • UDP 優勢:無須建立連線。
    • 說明:
      • TCP 需要三次交握(3-way handshake),會產生延遲(RTT)。
      • UDP 直接發送即可,這就是為什麼 DNS 選擇 UDP 的主因,因為查詢速度要快,不浪費時間建立連線。
  3. 狀態維護:
    • UDP 優勢:無連線狀態。
    • 說明:
      • TCP 需要在伺服器端維護大量的狀態(接收緩衝區、擁塞控制參數、序號等)。
      • UDP 伺服器不需要維護這些,因此同樣的系統資源下,UDP 伺服器通常能支援更多的活躍用戶端。
  4. 區段標頭:
    • UDP 優勢:標頭開銷小。
    • 說明:
      • TCP 的標頭至少有 20 bytes
      • 而 UDP 的標頭只有 8 bytes,對於網路頻寬錙銖必較的環境來說,UDP 更輕巧。

可靠性的迷思

使用 UDP 就代表傳輸一定不可靠嗎?

答案:不一定。

UDP 協定本身確實不可靠,但可在應用層(Application Layer)自己實作可靠性機制。

例如最新的 QUIC 協定(Google Chrome 和 HTTP/3 使用的核心),它的底層就是使用 UDP。

QUIC 在應用層自己寫了一套複雜的機制來處理掉包重傳、擁塞控制。

就像是你不想用郵局的掛號信服務(TCP),所以選擇寄平信(UDP),但是自己跟收信人約好,沒收到要打電話告訴你,由你自己補寄,這樣既得到了 UDP 的速度,又擁有了可靠性。

熱門應用程式所依賴的傳輸層協定

應用程式(Application)應用層協定傳輸層協定
電子郵件(E-mail)SMTPTCP
遠端存取(Remote terminal access)TelnetTCP
安全遠端存取(Secure remote terminal access)SSHTCP
網頁(Web)HTTP, HTTP/3TCP(for HTTP)、UDP(for HTTP/3)
檔案傳輸(File transfer)FTPTCP
遠端檔案伺服器(Remote file server)NFS通常為 UDP
串流多媒體(Streaming multimedia)DASHTCP
網路電話(Internet telephony)通常為專有協定UDP 或 TCP
網路管理(Network management)SNMP通常為 UDP
域名解析(Name translation)DNS通常為 UDP

Table Source:Computer Networking: A Top-Down Approach (8th ed., p. 227, Figure 3.6)

註:NFS,Network File System,為網路檔案系統,是一種基於主從式架構的分散式檔案系統協定。

3.3.1 UDP Segment Structure(UDP 區段結構)

UDP 的區段(Segment)結構設計反映了其輕量級的特性。

整個標頭(Header)只有 8 個位元組(Bytes),意即 UDP 對網路頻寬的佔用極小,非常適合那些不想因為傳輸協定而浪費太多流量的應用程式。

為什麼是這樣的結構?UDP 只需要足夠的資訊來完成兩件事:

  1. 把資料送到正確的應用程式(透過 Port)
  2. 簡單確認資料有沒有壞掉(透過 Checksum)。

多餘的欄位(如序號、確認號、視窗大小等)通通被移除了,因為那是 TCP 才需要的可靠性機制。

術語解析

  • 長度(Length):整個 UDP 區段的大小(包含標頭和資料)。
  • 檢查和(Checksum):用於檢查資料在傳輸過程中是否發生錯誤(例如位元翻轉)。

UDP 區段圖解

可將 UDP 區段(Segment)想像成一個包裹,該包裹由兩大部分組成:

  1. 標頭(Header)
  2. 資料欄位(Data field)。

見下圖 3.7,其 UDP 區段結構定義於 RFC 768 中。

image

Image Source:Computer Networking: A Top-Down Approach (8th ed., p. 228, Figure 3.7)

UDP 的結構非常整齊,一共只有 4 個標頭欄位,每個欄位佔 2 個位元組(16 bits)。

欄位名稱(Field Name)大小(Size)說明(Description)
來源埠號(Source Port #)16 bits(2 bytes)此為回信地址,當接收方想要回傳訊息時,可根據此埠號找到發送方。
目的埠號(Destination Port #)16 bits(2 bytes)此為目的地,接收端的傳輸層透過該號碼執行解多工(Demultiplexing),將資料交給正確的應用程式(如 DNS 伺服器)。
長度(Length)16 bits(2 bytes)指定了 UDP 區段的總長度(Header + Data)。
由於資料欄位的大小是可變的,所以需要此欄位來知道區段在哪裡結束。
檢查和(Checksum)16 bits(2 bytes)用於偵測錯誤,若接收方計算出來的校驗值跟這裡不符,就代表區段在移動過程中遭到更改。
應用資料(Application Data)不定長度又稱為 Payload(酬載),此為應用程式真正要傳送的內容(例如 DNS 查詢訊息或串流的音訊樣本)。

3.3.2 UDP Checksum(UDP 檢查和)

檢查和(Checksum)是 UDP 用來進行錯誤偵測(Error Detection)的機制。

其作用為判斷資料在從來源端傳輸到目的端的過程中,位元(Bits)是否發生了改變(例如 0 變成了 1)。

為什麼需要檢查和?

乙太網路(Ethernet)等連結層協定也有 CRC 檢測,但並不能保證所有經過的連結都有錯誤檢查,也不保證路由器內部的記憶體不會出錯。

為確保資料從來源端到目的端的過程中是完整的,UDP 必須在傳輸層提供最後一道防線。

UDP 檢查和限制:UDP 的檢查和只能「偵測」錯誤,無法「修正」錯誤(Error Correction),一旦發現錯誤,UDP 通常會直接丟棄該封包,或者回報應用程式有警告(取決於實作),但不會自動重傳。

術語解析

  • 1 的補數表示法(1’s Complement):一種二進位運算方式,簡單來說,就是將二進位數字中的 0 變 1,1 變 0(即反向)。
  • 1 的補數和(Sum of 1s complement):計算 Checksum 的核心演算法,將所有資料以 16-bit 為單位加總,若有溢位(Overflow),則將溢位的那個 bit 加回最低位。
  • 端對端原則:系統設計原則,意指某些功能(如錯誤檢查)必須在通訊系統的端點(發送端與接收端)基礎來實作,依賴底層(如連結層)是不夠的。

傳送端如何計算 Checksum

UDP 計算檢查和遵循 RFC 1071 的規範:

  1. 切割:將 UDP 區段(包含標頭和資料)看作是一連串的 16-bit 整數。
  2. 加總:將這些 16-bit 整數全部加起來。
    • 若在加法過程中產生進位(Carry),必須把進位加回結果的最低位(Least Significant Bit,LSB)。
  3. 取反:將加總後的結果進行 1 的補數(1’s complement)運算(0 變 1,1 變 0)。
  4. 填入:將最終結果填入 UDP 標頭的 Checksum 欄位。

計算範例

假設傳送以下三個 16-bit 的資料:

  1. (0110011001100000)2(0110011001100000)_2
  2. (0101010101010101)2(0101010101010101)_2
  3. (1000111100001100)2(1000111100001100)_2

計算步驟:

  1. 先加前兩個 16-bit 資料(即 1. 和 2.):$$(0110011001100000)_2 + (0101010101010101)_2 = (1011101110110101)_2$$ 得到 1. 和 2. 計算的總和結果。
  2. 接著將該總和結果再加上 3. 的資料:$$(1011101110110101)_2 + (1000111100001100)_2 = (10100101011000001)_2$$
    • 注意在此步驟中,最後的加總產生了溢位(第 17 個 bit 是 1)。
  3. 將最左邊溢位的 1 繞回到 LSB 並加上去:$$(0100101011000001)_2 + (0000000000000001)_2 = (0100101011000010)_2$$
  4. 取 1 的補數,將 3. 計算出的最終結果進行位元反轉: $$(1011010100111101)_2$$

這串 (1011010100111101)2(1011010100111101)_2 就會被放入 UDP 封包的 Checksum 欄位傳送出去。

接收端如何驗證

接收端收到封包後,做以下驗證:

  1. 將收到的所有資料(包含標頭、資料、以及剛剛算出來的 Checksum)全部視為 16-bit 整數。
  2. 將其全部加總(同樣使用 1 的補數和,有溢位要加回)。
  3. 檢查結果:
    • 若傳輸無誤,結果應全為 1 (1111111111111111)2(1111111111111111)_2
    • 若結果中有任何一個 bit 是 0,代表資料有誤。

為什麼結果會是全 1?試試看就知道了,因為 1 的補數法之特性會使其變成全都是 1。

深入探討:為什麼這麼麻煩?

既然底層網路(如 WiFi, Ethernet)都有一樣的機制(Checksum),為何 UDP 還要自己算一次?因為端對端原則(End-to-End Principle)。

潛在風險說明
連結層不保證並非所有連結層協定都有錯誤檢查,封包可能會經過一段沒有檢查機制的連結。
記憶體錯誤即使傳輸線路上沒有錯誤,封包在路由器的記憶體中排隊等待轉送時,可能因為硬體故障導致位元翻轉,此為連結層檢查不到的。

底層的檢查是有用但不足夠的,只有在端點(End System)進行檢查,才能確保從頭到尾的正確性。

總整理

UDP 為輕量級、無連線的傳輸層協定,幾乎直接與 IP 層溝通,只專注於兩件事:

  1. 多工/解多工:透過埠號(Port)區分不同的應用程式。
  2. 輕量錯誤檢查:透過檢查和(Checksum)確認資料完整性。

UDP 三不特性:

  1. 不保證資料送達
  2. 不保證資料順序
  3. 網路塞車時不主動降速(無壅塞控制)且不重傳。

選擇 UDP 的優勢:

優勢說明對比 TCP
1. 應用層控制權高想送就送,適合即時應用(如語音通話),寧可稍微掉幀也不要卡頓等待)。受壅塞控制限制,且會強制重傳。
2. 無須建立連線零連線延遲,隨送隨到,查詢速度極快(如 DNS)。需耗時進行三次交握(3-way handshake)。
3. 無連線狀態伺服器不需維護接收緩衝區或序號,相同資源下能負載更多用戶。需消耗大量伺服器資源維護狀態。
4. 標頭開銷極小標頭僅 8 bytes,對頻寬錙銖必較的環境極為友善。標頭至少 20 bytes。

可靠性迷思與常見應用:

  • 迷思:用 UDP 就一定不可靠嗎?
    • 不一定。UDP 本身不可靠,但可靠性可以建立在「應用層」,例如 HTTP/3 底層的 QUIC 協定即使用 UDP,並由應用層自己寫一套機制來處理掉包重傳與壅塞控制,兼顧了速度與可靠性。
  • UDP 常見應用:DNS 查詢、即時影音串流、VoIP(網路電話)、SNMP(網路管理)。

熱門應用程式所依賴的傳輸層協定:

應用程式(Application)應用層協定傳輸層協定
電子郵件(E-mail)SMTPTCP
遠端存取(Remote terminal access)TelnetTCP
安全遠端存取(Secure remote terminal access)SSHTCP
網頁(Web)HTTP, HTTP/3TCP(for HTTP)、UDP(for HTTP/3)
檔案傳輸(File transfer)FTPTCP
遠端檔案伺服器(Remote file server)NFS通常為 UDP
串流多媒體(Streaming multimedia)DASHTCP
網路電話(Internet telephony)通常為專有協定UDP 或 TCP
網路管理(Network management)SNMP通常為 UDP
域名解析(Name translation)DNS通常為 UDP

UDP 區段結構(Segment Structure)

UDP 標頭非常精簡,共有 8 bytes,由 4 個欄位組成(每個欄位佔 16 bits / 2 bytes):

  1. 來源埠號(Source Port):回信地址。
  2. 目的埠號(Destination Port):接收端用來執行解多工,將資料交給正確的應用程式。
  3. 長度(Length):UDP 區段的總長度(Header + Payload),用來標示區段結尾。
  4. 檢查和(Checksum):偵測資料在傳輸過程中是否損壞。
  • 應用資料(Payload):實際要傳送的內容(如 DNS 查詢訊息)。

image

UDP 檢查和(Checksum)

目的:用於錯誤偵測(Error Detection),需注意,UDP 只能偵測、不能修正錯誤,發現錯誤通常會直接丟棄封包。

為何需要?(端對端原則 End-to-End Principle):即使底層網路(如乙太網)有檢查機制,也無法防範路由器內部記憶體故障導致的位元翻轉,須在終端(發送端與接收端)進行最終確認才能確保萬無一失。

計算與驗證機制(1 的補數和):

  1. 切割與加總:將區段看作一連串 16-bit 整數並加總,若產生溢位(Overflow),必須將最左邊溢位的 bit 加回最低位(LSB)。
  2. 傳送端(取反):將加總結果進行 1 的補數運算(0 變 1,1 變 0),填入 Checksum 欄位。
  3. 接收端(驗證):將收到的所有資料(含 Checksum)以同樣方式加總,若傳輸無誤,因為 1 的補數特性,結果必定為全 1,即 (1111111111111111)2(1111111111111111)_2。若出現任何 0,代表資料有誤。