每一個(gè)程序員應(yīng)該都知道TCP,UDP協(xié)議。UDP是用戶數(shù)據(jù)報(bào)文協(xié)議,屬于OSI模型中的傳輸層。它是一種無(wú)連接的協(xié)議,也就說上一報(bào)文和下一報(bào)文在協(xié)議層沒有任何聯(lián)系,同時(shí)提供了簡(jiǎn)單的不可靠的傳輸服務(wù)。
也就是說UDP是不可靠的,如果要想讓數(shù)據(jù)可靠,就需要在業(yè)務(wù)層做糾錯(cuò)和檢錯(cuò)功能。比如:TFTP。
那可能就會(huì)有同學(xué)問了,既然是不可靠的,為什么不直接使用IP協(xié)議呢?還要這么大費(fèi)周章增加一種協(xié)議UDP呢?
其實(shí)其中一個(gè)最重要的原因就是IP協(xié)議中沒有端口(port)的概念,它只是規(guī)定了兩臺(tái)主機(jī)之間的通信,并沒有解決不同主機(jī)上應(yīng)用程序之間的通信。如果一個(gè)主機(jī)上的多個(gè)應(yīng)用程序需要通信,直接用IP協(xié)議就無(wú)法數(shù)據(jù)區(qū)分?jǐn)?shù)據(jù)到底哪個(gè)應(yīng)用程序了。
可以理解為一個(gè)端口就是一個(gè)通信通道,當(dāng)然UDP在IP協(xié)議的基礎(chǔ)上增加了一些功能,所以我們來(lái)總結(jié)下:
- UDP無(wú)連接,沒有連接。所以它的發(fā)送和接受的開銷就會(huì)小很多。
- UDP不保證數(shù)據(jù)可靠交付,只是盡最大可能。所以不需要維護(hù)復(fù)雜的連接關(guān)系。
- UDP是面向報(bào)文的,添加在應(yīng)用層下來(lái)數(shù)據(jù)頭部,直接塞給IP層。
- UDP沒有擁塞控制
- UDP至支持多播。
- UDP頭部小,說明傳輸更多的數(shù)據(jù)內(nèi)容
下圖展示是UDP和上下層的關(guān)系
UDP的首部到底是怎樣的呢?
先看下圖:
從圖中可以看出,UDP的首部由四部分組成:
- 各16bit的來(lái)源端口和目的端口用來(lái)標(biāo)記發(fā)送和接受的應(yīng)用進(jìn)程。因?yàn)閁DP不需要應(yīng)答,所以來(lái)源端口是可選的,如果來(lái)源端口不用,那么置為零。當(dāng)運(yùn)輸層從IP層收到UDP數(shù)據(jù)報(bào)時(shí),就是根據(jù)首部中的目的端口,把UDP數(shù)據(jù)報(bào)通過相應(yīng)的端口,上交最后的終點(diǎn)--應(yīng)用程序。
- 如果接收方UDP發(fā)現(xiàn)收到的報(bào)文中的目的端口號(hào)不正確,就會(huì)丟棄改報(bào)文,并由網(wǎng)際控制協(xié)議ICMP發(fā)送“端口不可達(dá)”差錯(cuò)報(bào)文給發(fā)送方。ICMP應(yīng)用Traceroute,就是讓發(fā)送的UDP用戶數(shù)據(jù)報(bào)故意使用一個(gè)非法的UDP端口,結(jié)果ICMP返回“端口不可達(dá)”差錯(cuò)報(bào)文,因而達(dá)到了測(cè)試的目的。
- 在目的端口后面是長(zhǎng)度固定的以字節(jié)為單位的報(bào)文長(zhǎng)度域,用來(lái)指定UDP數(shù)據(jù)報(bào)包括數(shù)據(jù)部分的長(zhǎng)度,長(zhǎng)度最小值為8byte。
- 首部剩下地16bit是用來(lái)對(duì)首部和數(shù)據(jù)部分一起做校驗(yàn)和(Checksum)的,這部分是可選的,但在實(shí)際應(yīng)用中一般都使用這一功能。
- UDP和TCP的校驗(yàn)和都覆蓋到了他們的首部和數(shù)據(jù),而IP首部的校驗(yàn)和只覆蓋了IP首部。
UDP和socket怎樣配合使用
隨著我們進(jìn)入傳輸層,我們也可以調(diào)用操作系統(tǒng)中的API,來(lái)構(gòu)建socket。Socket是操作系統(tǒng)提供的一個(gè)編程接口,它用來(lái)代表某個(gè)網(wǎng)絡(luò)通信。應(yīng)用程序通過socket來(lái)調(diào)用系統(tǒng)內(nèi)核中處理網(wǎng)絡(luò)協(xié)議的模塊,而這些內(nèi)核模塊會(huì)負(fù)責(zé)具體的網(wǎng)絡(luò)協(xié)議的實(shí)施。
這樣,我們可以讓內(nèi)核來(lái)接收網(wǎng)絡(luò)協(xié)議的細(xì)節(jié),而我們只需要提供所要傳輸?shù)膬?nèi)容就可以了,內(nèi)核會(huì)幫我們控制格式,并進(jìn)一步向底層封裝。因此,在實(shí)際應(yīng)用中,我們并不需要知道具體怎么構(gòu)成一個(gè)UDP包,而只需要提供相關(guān)信息(比如IP地址,比如端口號(hào),比如所要傳輸?shù)男畔?,操作系統(tǒng)內(nèi)核會(huì)在傳輸之前會(huì)根據(jù)我們提供的相關(guān)信息構(gòu)成一個(gè)合格的UDP包(以及下層的包和幀)。看下圖吧。
UDP使用場(chǎng)景
- 需要資源少,在網(wǎng)絡(luò)情況比較好的內(nèi)網(wǎng),或者對(duì)于丟包不敏感的應(yīng)用。如DHCP協(xié)議就是基于UDP的。一般的獲取IP地址都是內(nèi)網(wǎng)請(qǐng)求,而且一次獲取不到IP又沒事。又比如基于UDP的RTP,TFTP,丟一幀數(shù)據(jù)問題也不大。再比如一些設(shè)備發(fā)現(xiàn)協(xié)議等等。
- 不需要一對(duì)一溝通,建立連接,而是可以廣播的應(yīng)用。DHCP就是一種廣播的形式。VXLAN也是需要用到組播,也是基于UDP協(xié)議的。
- 需要處理速度快,時(shí)延低,可以容忍少數(shù)丟包,但是要求即便網(wǎng)絡(luò)擁塞,也毫不退縮,一往無(wú)前的時(shí)候。
- QUIC是google提出的一種基于UDP改進(jìn)的通信協(xié)議,其目的是降低網(wǎng)絡(luò)通信的延遲,提供更好的用戶互動(dòng)體驗(yàn)。
結(jié)語(yǔ)
UDP沒有TCP那么復(fù)雜,但是網(wǎng)絡(luò)體系中不可缺少的協(xié)議。需要熟練的掌握該協(xié)議。