UDP 與 TCP 兩種傳輸協(xié)議是 IP 協(xié)議簇的核心成員,1980 年發(fā)布的 RFC 768 定義了 UDP 協(xié)議[^1],我們可以通過它在多個計算機連接構成的網(wǎng)絡中傳遞數(shù)據(jù)。常見的 DNS 協(xié)議就可以使用 UDP 協(xié)議獲取域名解析的結果[^2]。
UDP 是能夠傳輸數(shù)據(jù)的最簡單的協(xié)議,它的協(xié)議首部(也稱作協(xié)議頭)只有 8 個字節(jié),很多人,尤其是應屆畢業(yè)生都能通過死機硬背暫時記住 UDP 協(xié)議頭包含的內容,但是知道協(xié)議頭的內容不代表我們真正理解背后的原因。本文會分析為什么只有 8 個字節(jié)的 UDP 協(xié)議能夠傳輸數(shù)據(jù),相信這篇文章能幫助你更好地理解 UDP 協(xié)議頭中字段的作用。
udp-header
圖 1 - UDP 協(xié)議頭
UDP 協(xié)議頭中只包含 4 個字段,分別是源端口、目的端口、長度和校驗碼,其中每一個字段都占 16 比特,即 2 字節(jié),這 4 個字段的作用如下:
- 源端口是一個可選字段,它表示發(fā)送方進程的端口號,接收方可以使用該字段(不一定準確)向發(fā)送方發(fā)送信息;
- 目的端口是數(shù)據(jù)報接收方的端口號,它只在目標的 IP 地址下才有意義;
- 長度是協(xié)議頭和數(shù)據(jù)報中數(shù)據(jù)長度的總和,表示整個數(shù)據(jù)報的大小;
- 校驗碼使用 IP 首部、UDP 首部和數(shù)據(jù)報中的數(shù)據(jù)進行計算[^3],接收方可以通過校驗碼驗證數(shù)據(jù)的準確性,發(fā)現(xiàn)傳輸過程中出現(xiàn)的問題;
通過 Wireshark 抓包來查看實際使用中 UDP 協(xié)議首部的值。當我們執(zhí)行 dig baidu.com 命令時,本地就會向 DNS 服務器發(fā)送 DNS 查詢,下面就是一個 DNS 查詢中 UDP 首部的例子:
0000 ff 7c 00 35 00 23 c2 6e
上述 UDP 首部中四個字段對應的值如下:
字段 | 數(shù)據(jù) |
---|---|
源端口 | 0xff7c = 65404 |
目的端口 | 0x0035 = 53 |
長度 | 0x0023 = 35 |
校驗碼 | 0xc26e |
由于 DNS 協(xié)議使用的端口是 53[^4],所以上述 UDP 首部中的目的端口就是 53。源端口就是本地發(fā)出 DNS 請求的端口,該端口也用來接收 DNS 響應。
定義 UDP 協(xié)議的 RFC 768 文檔只有 3 頁,由于 UDP 協(xié)議既不需要保證送達,也不需要保證順序,所以它沒有 TCP 協(xié)議那么復雜。TCP 協(xié)議中的三次握手[^5]、擁塞控制算法和重傳策略等機制都是為了提供可靠性所付出的必要代價,但是 UDP 協(xié)議不需要這些策略,它只盡力保證數(shù)據(jù)報的送達。
我們今天來分析一下為什么首部只有 8 個字節(jié)的 UDP 協(xié)議能夠將數(shù)據(jù)傳輸?shù)侥康牡夭⒂商囟ǖ姆战邮蘸吞幚怼N覀兛梢詫玫綉弥g的傳輸過程分成兩個部分:主機到主機的數(shù)據(jù)傳輸和主機到應用的數(shù)據(jù)轉發(fā)。
- UDP 協(xié)議底層的網(wǎng)際協(xié)議(Internet Protocol,IP)會負責數(shù)據(jù)包在主機之間的傳輸;
- UDP 協(xié)議首部的端口號用于定位處理數(shù)據(jù)的具體進程并轉發(fā)數(shù)據(jù);
我們都說 UDP 協(xié)議是傳輸層協(xié)議,但是真正在主機間完成『數(shù)據(jù)傳輸』工作的是 IP 協(xié)議,UDP 協(xié)議只起到了定位具體進程的作用。
數(shù)據(jù)傳輸
RFC768 在介紹 UDP 協(xié)議時強調 UDP 協(xié)議假設底層會使用 IP 協(xié)議。IP 協(xié)議是 TCP/IP 協(xié)議棧的核心成員,它不保證端到端數(shù)據(jù)的可靠性和順序,也不包含流控制等機制,其作用就是從來源向目的地傳輸數(shù)據(jù)包[^6]。在本文中,我們只需要知道 IP 協(xié)議頭中包含源 IP 和目的 IP,就不展開介紹 IP 協(xié)議的具體實現(xiàn)了,感興趣的讀者可以閱讀 RFC791 和相關文檔了解更多的內容。
『UDP 協(xié)議只能盡力送達數(shù)據(jù)』這一說法『繼承』自 UDP 的下層協(xié)議,也就是 IP 協(xié)議。只包含了兩個端口號的 UDP 協(xié)議本身是無法提供路由和尋址功能的,它還是需要下層的協(xié)議來解決這個問題。
上面提到的這種各司其職的設計源于網(wǎng)絡通訊協(xié)議的分層結構。抽象是計算機科學中的基礎概念,通過定義良好的接口、構建抽象層,我們可以減少同時需要關注的問題,讓每一層都能聚焦到需要處理的問題上。TCP/IP 協(xié)議簇將通信過程分成了四個抽象層,分別是:鏈接層(Link)、網(wǎng)絡層(Internet)、傳輸層(Transport)和應用層(Application)[^7]。
tcp-ip-layers
圖 2 - TCP/IP 協(xié)議簇的抽象層
不同的抽象層有著完全不同的功能,我們來看一下網(wǎng)絡層和傳輸層的職責。TCP 和 UDP 等傳輸層協(xié)議的主要作用是為應用建立基本的數(shù)據(jù)管道,為特定任務提供數(shù)據(jù)傳輸?shù)墓δ埽欢?IP 等網(wǎng)絡層協(xié)議的主要作用是尋址和路由,它能夠幫助我們將數(shù)據(jù)發(fā)送目標的主機。
簡單總結一下,UDP 協(xié)議下層的 IP 協(xié)議實現(xiàn)數(shù)據(jù)包的傳輸,雖然 UDP 屬于傳輸層協(xié)議,但是其本身沒有提供主機到主機的數(shù)據(jù)傳輸能力。
進程定位
在軟件層面上,端口是用來表示特定進程或者特定類型網(wǎng)絡服務的邏輯概念[^8],計算機硬件中也有端口的概念,但是這里說的端口是沒有實體的。當主機接收到 IP 數(shù)據(jù)包時會根據(jù)協(xié)議號交給不同的模塊處理,TCP 和 UDP 協(xié)議會根據(jù)端口號確定送給對應的進程處理。
雖然 TCP 和 UDP 協(xié)議中都有端口號這一概念,但是因為它們兩者的端口不在一個命名空間下(TCP 和 UDP 是兩套命名空間),所以 TCP 和 UDP 可以同時使用相同的端口號,例如:53/TCP 和 53/UDP,這兩個端口號后的服務都處理 DNS 請求。從這一點來看,只有通過 IP 地址、傳輸層協(xié)議和端口號三者才能在網(wǎng)絡上定位到具體的服務,只憑借 IP 地址和端口號是不可行的。
ip-and-tcp-udp-ports
圖 3 - TCP 和 UDP 的重復端口號
UDP 協(xié)議中的兩個端口號占據(jù)了 UDP 協(xié)議頭的一半開銷,這從側面表明了端口號在 UDP 協(xié)議的重要地位和 UDP 協(xié)議的主要功能。接收 IP 數(shù)據(jù)包的主機可以使用目的端口號找到特定的進程,該進程也可以使用數(shù)據(jù)包中的源端口號向發(fā)送方回復數(shù)據(jù)。
ports-and-processes
圖 4 - 端口號和進程
TCP 和 UDP 的端口號是主機和進程的中間層,進程和端口號既可以是一對一的關系,也可以是一對多的關系,端口號的引入可以讓同一個主機上的多個進程對外提供服務,也可以讓一個進程對外提供多個服務。有了端口號,想要訪問主機服務的請求也不需要使用進程標識符等方式定位提供服務的具體進程。
總結
簡單回答一下本文提出的問題:UDP 協(xié)議利用下層的 IP 協(xié)議提供基本的數(shù)據(jù)傳輸能力,它的作用就是引入端口號的概念讓同一主機可以同時提供對外多個服務,由于不保證可靠性,所以協(xié)議本身只占用 8 個字節(jié)。
在理想情況下,我們可以在 IP 協(xié)議上構建新的傳輸層協(xié)議實現(xiàn)特定的需求,不過在實際操作中由于協(xié)議號的限制,新的傳輸層協(xié)議無法被大量部署的網(wǎng)絡地址轉換(Network address translation,NAT)[^9]設備識別和支持,所以使用這種方式構建新的傳輸層協(xié)議在實踐中難以落實。
注1:協(xié)議號是 IP 首部中的一個字段,它表示當前報文數(shù)據(jù)區(qū)使用的協(xié)議,最常見的 TCP 和 UDP 協(xié)議的協(xié)議號分別是 6 和 17。
注2:SCTP 協(xié)議[^10]就是一個 RFC 標準中的傳輸層協(xié)議,但是 NAT 設備的兼容性問題會導致 SCTP 報文被丟棄。
由于 UDP 協(xié)議非常簡單,很多新的傳輸層協(xié)議都會基于 UDP 實現(xiàn),例如:Google 的 QUIC 協(xié)議[^11]。到最后,我們還是來看一些比較開放的相關問題,有興趣的讀者可以仔細思考一下下面的問題:
- UDP 協(xié)議中的長度和校驗碼可以被省略么?為什么?
- 除了 UDP 和 TCP 協(xié)議,其他基于 IP 的傳輸層協(xié)議有沒有端口號的概念?
掃碼二維碼 獲取免費視頻學習資料
- 本文固定鏈接: http://www.wangchenghua.com/post/7239/
- 轉載請注明:轉載必須在正文中標注并保留原文鏈接
- 掃碼: 掃上方二維碼獲取免費視頻資料