八個字節的 UDP 如何傳輸數據!細節,都是細節!



 

UDP 與 TCP 兩種傳輸協議是 IP 協議簇的核心成員,1980 年發布的 RFC 768 定義了 UDP 協議[^1],我們可以通過它在多個計算機連接構成的網絡中傳遞數據。

常見的 DNS 協議就可以使用 UDP 協議獲取域名解析的結果[^2]。

UDP 是能夠傳輸數據的最簡單的協議,它的協議首部(也稱作協議頭)只有 8 個字節,很多人,尤其是應屆畢業生都能通過死機硬背暫時記住 UDP 協議頭包含的內容,但是知道協議頭的內容不代表我們真正理解背后的原因。

本文會分析為什么只有 8 個字節的 UDP 協議能夠傳輸數據,相信這篇文章能幫助你更好地理解 UDP 協議頭中字段的作用。


圖 1 - UDP 協議頭

UDP 協議頭中只包含 4 個字段,分別是源端口、目的端口、長度和校驗碼,其中每一個字段都占 16 比特,即 2 字節,這 4 個字段的作用如下:

    ✪ 源端口是一個可選字段,它表示發送方進程的端口號,接收方可以使用該字段(不一定准確)向發送方發送信息;

    ✪ 目的端口是數據報接收方的端口號,它只在目標的 IP 地址下才有意義;

    ✪ 長度是協議頭和數據報中數據長度的總和,表示整個數據報的大小;

    ✪ 校驗碼使用 IP 首部、UDP 首部和數據報中的數據進行計算[^3],接收方可以通過校驗碼驗證數據的准確性,發現傳輸過程中出現的問題;

通過 Wireshark 抓包來查看實際使用中 UDP 協議首部的值。當我們執行 dig baidu.com 命令時,本地就會向 DNS 服務器發送 DNS 查詢,下面就是一個 DNS 查詢中 UDP 首部的例子:

0000  ff 7c 00 35 00 23 c2 6e

上述 UDP 首部中四個字段對應的值如下:


 

由於 DNS 協議使用的端口是 53[^4],所以上述 UDP 首部中的目的端口就是 53。源端口就是本地發出 DNS 請求的端口,該端口也用來接收 DNS 響應。

定義 UDP 協議的 RFC 768 文檔只有 3 頁,由於 UDP 協議既不需要保證送達,也不需要保證順序,所以它沒有 TCP 協議那么復雜。

TCP 協議中的三次握手[^5]、擁塞控制算法和重傳策略等機制都是為了提供可靠性所付出的必要代價,但是 UDP 協議不需要這些策略,它只盡力保證數據報的送達。

我們今天來分析一下為什么首部只有 8 個字節的 UDP 協議能夠將數據傳輸到目的地並由特定的服務接收和處理。

我們可以將應用到應用之間的傳輸過程分成兩個部分:主機到主機的數據傳輸和主機到應用的數據轉發。

    ✪ UDP 協議底層的網際協議(Internet Protocol,IP)會負責數據包在主機之間的傳輸;

    ✪ UDP 協議首部的端口號用於定位處理數據的具體進程並轉發數據;

我們都說 UDP 協議是傳輸層協議,但是真正在主機間完成『數據傳輸』工作的是 IP 協議,UDP 協議只起到了定位具體進程的作用。

 

數據傳輸

RFC768 在介紹 UDP 協議時強調 UDP 協議假設底層會使用 IP 協議。IP 協議是 TCP/IP 協議棧的核心成員,它不保證端到端數據的可靠性和順序,也不包含流控制等機制,其作用就是從來源向目的地傳輸數據包[^6]。

『UDP 協議只能盡力送達數據』這一說法『繼承』自 UDP 的下層協議,也就是 IP 協議。只包含了兩個端口號的 UDP 協議本身是無法提供路由和尋址功能的,它還是需要下層的協議來解決這個問題。

上面提到的這種各司其職的設計源於網絡通訊協議的分層結構。抽象是計算機科學中的基礎概念,通過定義良好的接口、構建抽象層,我們可以減少同時需要關注的問題,讓每一層都能聚焦到需要處理的問題上。

TCP/IP 協議簇將通信過程分成了四個抽象層,分別是:鏈接層(Link)、網絡層(Internet)、傳輸層(Transport)和應用層(Application)[^7]。


 

圖 2 - TCP/IP 協議簇的抽象層

不同的抽象層有着完全不同的功能,我們來看一下網絡層和傳輸層的職責。

TCP 和 UDP 等傳輸層協議的主要作用是為應用建立基本的數據管道,為特定任務提供數據傳輸的功能;而 IP 等網絡層協議的主要作用是尋址和路由,它能夠幫助我們將數據發送目標的主機。

簡單總結一下,UDP 協議下層的 IP 協議實現數據包的傳輸,雖然 UDP 屬於傳輸層協議,但是其本身沒有提供主機到主機的數據傳輸能力。

 

進程定位

在軟件層面上,端口是用來表示特定進程或者特定類型網絡服務的邏輯概念[^8],計算機硬件中也有端口的概念,但是這里說的端口是沒有實體的。

當主機接收到 IP 數據包時會根據協議號交給不同的模塊處理,TCP 和 UDP 協議會根據端口號確定送給對應的進程處理。

雖然 TCP 和 UDP 協議中都有端口號這一概念,但是因為它們兩者的端口不在一個命名空間下(TCP 和 UDP 是兩套命名空間),所以 TCP 和 UDP 可以同時使用相同的端口號。

例如:53/TCP 和 53/UDP,這兩個端口號后的服務都處理 DNS 請求。從這一點來看,只有通過 IP 地址、傳輸層協議和端口號三者才能在網絡上定位到具體的服務,只憑借 IP 地址和端口號是不可行的。


 

圖 3 - TCP 和 UDP 的重復端口號

UDP 協議中的兩個端口號占據了 UDP 協議頭的一半開銷,這從側面表明了端口號在 UDP 協議的重要地位和 UDP 協議的主要功能。

接收 IP 數據包的主機可以使用目的端口號找到特定的進程,該進程也可以使用數據包中的源端口號向發送方回復數據。


 

圖 4 - 端口號和進程

TCP 和 UDP 的端口號是主機和進程的中間層,進程和端口號既可以是一對一的關系,也可以是一對多的關系,端口號的引入可以讓同一個主機上的多個進程對外提供服務,也可以讓一個進程對外提供多個服務。

有了端口號,想要訪問主機服務的請求也不需要使用進程標識符等方式定位提供服務的具體進程。

 

總結

簡單回答一下本文提出的問題:UDP 協議利用下層的 IP 協議提供基本的數據傳輸能力,它的作用就是引入端口號的概念讓同一主機可以同時提供對外多個服務,由於不保證可靠性,所以協議本身只占用 8 個字節。

在理想情況下,我們可以在 IP 協議上構建新的傳輸層協議實現特定的需求,不過在實際操作中由於協議號的限制,新的傳輸層協議無法被大量部署的網絡地址轉換(Network address translation,NAT)[^9]設備識別和支持,所以使用這種方式構建新的傳輸層協議在實踐中難以落實。

注1:協議號是 IP 首部中的一個字段,它表示當前報文數據區使用的協議,最常見的 TCP 和 UDP 協議的協議號分別是 6 和 17。

注2:SCTP 協議[^10]就是一個 RFC 標准中的傳輸層協議,但是 NAT 設備的兼容性問題會導致 SCTP 報文被丟棄。

由於 UDP 協議非常簡單,很多新的傳輸層協議都會基於 UDP 實現,例如:Google 的 QUIC 協議[^11]。

到最后,我們還是來看一些比較開放的相關問題,有興趣的讀者可以仔細思考一下下面的問題:

    ✪ UDP 協議中的長度和校驗碼可以被省略么?為什么?

    ✪ 除了 UDP 和 TCP 協議,其他基於 IP 的傳輸層協議有沒有端口號的概念?


 

不管你是轉行也好,初學也罷,進階也可,如果你想學編程,進階程序員~

【值得關注】我的 編程學習交流俱樂部!【點擊進入】

全棧程序員正在等你加入~


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM