柚子快報(bào)邀請碼778899分享:網(wǎng)絡(luò) 傳輸層協(xié)議UDP詳解
柚子快報(bào)邀請碼778899分享:網(wǎng)絡(luò) 傳輸層協(xié)議UDP詳解
目錄
一.? ?知識(shí)準(zhǔn)備
1.1? ?傳輸層
1.2? ?重識(shí)端口號(hào)
二.? ?UDP協(xié)議
三.? ?UDP協(xié)議特點(diǎn)
一.? ?知識(shí)準(zhǔn)備
1.1? ?傳輸層
前面已經(jīng)講過,HTTP協(xié)議是應(yīng)用層協(xié)議,在此之前,我們短暫的認(rèn)為HTTP是直接通過應(yīng)用層與外界通信的。但是我們要知道,應(yīng)用層需要向下將數(shù)據(jù)傳到傳輸層,再由傳輸層向下傳送。最終才能通過網(wǎng)絡(luò)傳輸?shù)浇邮辗健?/p>
傳輸層負(fù)責(zé)保證可靠性傳輸,確保數(shù)據(jù)能夠可靠地傳送到接收方。
1.2? ?重識(shí)端口號(hào)
端口號(hào)的作用是標(biāo)識(shí)主機(jī)上的一個(gè)唯一的進(jìn)程。當(dāng)目標(biāo)主機(jī)接收到數(shù)據(jù)之后,需要自底向上進(jìn)行數(shù)據(jù)的傳送,最后根據(jù)端口號(hào)來確定該傳給上層哪個(gè)進(jìn)程。
端口號(hào)是屬于傳輸層的概念,因此在傳輸層協(xié)議中就會(huì)包含與端口相關(guān)的字段。
五元組標(biāo)識(shí)一個(gè)通信:
在TCP/IP協(xié)議中,用“源IP地址”、“源端口號(hào)”、“目的IP地址”、“目的端口號(hào)”、“協(xié)議號(hào)”這樣一個(gè)五元組來標(biāo)識(shí)一個(gè)通信。
?像上圖這樣,有多臺(tái)主機(jī)訪問服務(wù)器,這些主機(jī)中可能有多個(gè)進(jìn)程在同時(shí)訪問服務(wù)器。
而這臺(tái)服務(wù)器收到請求之后,根據(jù)五元組分離出“源IP地址”、“源端口號(hào)”、“目的IP地址”、“目的端口號(hào)”、“協(xié)議號(hào)”這些元素。
根據(jù)目的IP地址和目的端口號(hào)確定這些主機(jī)確實(shí)是想跟這臺(tái)服務(wù)器通信。然后根據(jù)源IP地址和源端口號(hào)確定是哪臺(tái)主機(jī)上的哪個(gè)進(jìn)程想要通信。最后根據(jù)協(xié)議號(hào)確定該用什么類型進(jìn)行通信。
也可以通過netstat命令查看五元組信息。
其中Local Address就是源IP和源端口號(hào),F(xiàn)oreign Address就是目的IP和目的端口號(hào)。而Proto代表的就是協(xié)議類型。
端口號(hào)范圍劃分:
? 0 - 1023: 知名端口號(hào), HTTP, FTP, SSH 等這些廣為使用的應(yīng)用層協(xié)議, 他們的端口號(hào)都是固定的。
例如:
? ssh 服務(wù)器, 使用 22 端口
? ftp 服務(wù)器, 使用 21 端口
? telnet 服務(wù)器, 使用 23 端口
? http 服務(wù)器, 使用 80 端口
? https 服務(wù)器, 使用 443
? 1024 - 65535: 操作系統(tǒng)動(dòng)態(tài)分配的端口號(hào). 客戶端程序的端口號(hào), 就是由操作系統(tǒng)從這個(gè)范圍分配的。
協(xié)議號(hào) VS? 端口號(hào):
協(xié)議號(hào)是存在于IP報(bào)頭當(dāng)中的,其長度是8位。協(xié)議號(hào)指明了數(shù)據(jù)報(bào)所攜帶的數(shù)據(jù)是使用的何種協(xié)議,以便讓目的主機(jī)的IP層知道應(yīng)該將該數(shù)據(jù)交付給傳輸層的哪個(gè)協(xié)議進(jìn)行處理。端口號(hào)是存在于UDP和TCP報(bào)頭當(dāng)中的,其長度是16位。端口號(hào)的作用是唯一標(biāo)識(shí)一臺(tái)主機(jī)上的某個(gè)進(jìn)程。協(xié)議號(hào)是作用于傳輸層和網(wǎng)絡(luò)層之間的,而端口號(hào)是作用于應(yīng)用層于傳輸層之間的。
兩個(gè)問題:
?一個(gè)端口號(hào)是否可以被多個(gè)進(jìn)程綁定?
這是絕對不行的,因?yàn)槲覀兪峭ㄟ^端口號(hào)來標(biāo)識(shí)唯一的一個(gè)進(jìn)程,如果我們將一個(gè)端口號(hào)綁定多個(gè)進(jìn)程。通信時(shí)就不知道該與哪個(gè)進(jìn)程通信。
一個(gè)進(jìn)程是否可以綁定多個(gè)端口號(hào)??
這個(gè)是可以的,與“端口號(hào)唯一標(biāo)識(shí)一個(gè)進(jìn)程”不沖突,只不過現(xiàn)在變成了一個(gè)進(jìn)程可以由多個(gè)端口號(hào)來標(biāo)識(shí)。
二.? ?UDP協(xié)議
網(wǎng)絡(luò)套接字編程時(shí)用到的各種接口,是位于應(yīng)用層和傳輸層之間的一層系統(tǒng)調(diào)用接口,這些接口是系統(tǒng)提供的,我們可以通過這些接口搭建上層應(yīng)用,比如HTTP。我們經(jīng)常說HTTP是基于TCP的,實(shí)際就是因?yàn)镠TTP在TCP套接字編程上搭建的。
而socket接口往下的傳輸層實(shí)際就是由操作系統(tǒng)管理的,因此UDP是屬于內(nèi)核當(dāng)中的,是操作系統(tǒng)本身協(xié)議棧自帶的,其代碼不是由上層用戶編寫的,UDP的所有功能都是由操作系統(tǒng)完成,因此網(wǎng)絡(luò)也是操作系統(tǒng)的一部分。
16位源端口號(hào):表示數(shù)據(jù)從哪里來。16位目的端口號(hào):表示數(shù)據(jù)要到哪里去。16位UDP長度:表示整個(gè)數(shù)據(jù)報(bào)(UDP首部 + UDP數(shù)據(jù))的長度。16位UDP檢驗(yàn)和:如果UDP報(bào)文的檢驗(yàn)和出錯(cuò),就會(huì)直接將報(bào)文丟棄。
我們在應(yīng)用層看到的端口號(hào)大部分是16位的,其根本原因就是因?yàn)閭鬏攲訁f(xié)議當(dāng)中的端口號(hào)就是16位的。
UDP如何實(shí)現(xiàn)報(bào)頭與數(shù)據(jù)的分離?
?可以看到,報(bào)頭里面只有四個(gè)部分,每個(gè)部分的長度都是16位,總共8字節(jié)。所以可以將報(bào)頭看做定長的,那么只需在讀取的時(shí)候?qū)⑶懊?字節(jié)的報(bào)頭讀完,剩下的就是數(shù)據(jù)。
UDP如何決定將有效載荷交付給上層哪一個(gè)協(xié)議?
UDP上層也有很多應(yīng)用層協(xié)議,因此UDP必須想辦法將有效載荷交給對應(yīng)的上層協(xié)議,也就是交給應(yīng)用層對應(yīng)的進(jìn)程。
應(yīng)用層的每一個(gè)網(wǎng)絡(luò)進(jìn)程都會(huì)綁定一個(gè)端口號(hào),服務(wù)端進(jìn)程必須顯示綁定一個(gè)端口號(hào),客戶端進(jìn)程則是由系統(tǒng)綁定的一個(gè)端口號(hào)。UDP就是通過報(bào)頭當(dāng)中的目的端口號(hào)來找到對應(yīng)的應(yīng)用層進(jìn)程的。
特別注意:內(nèi)核中用哈希的方式維護(hù)了端口號(hào)與進(jìn)程ID之間的映射關(guān)系,因此傳輸層可以通過端口號(hào)得到對應(yīng)的進(jìn)程ID,進(jìn)而找到對應(yīng)的應(yīng)用層進(jìn)程。?
三.? ?UDP協(xié)議特點(diǎn)
UDP傳輸?shù)倪^程類似于寄信,其特點(diǎn)如下:
無連接:知道對端的IP和端口號(hào)就可以直接進(jìn)行通信,無需等待連接。不可靠:沒有確認(rèn)機(jī)制,沒有重傳機(jī)制;如果因?yàn)榫W(wǎng)絡(luò)故障該段無法發(fā)到對方, UDP 協(xié)議層也不會(huì)給應(yīng)用層返回任何錯(cuò)誤信息。面向數(shù)據(jù)報(bào):不能夠靈活的控制讀寫數(shù)據(jù)的次數(shù)和數(shù)量。
?注意:報(bào)文在網(wǎng)絡(luò)中進(jìn)行路由轉(zhuǎn)發(fā)時(shí),并不是每一個(gè)報(bào)文選擇的路由路徑都是一樣的,因此報(bào)文發(fā)送的順序和接收的順序可能是不同的。
面向數(shù)據(jù)報(bào):
應(yīng)用層交給 UDP 多長的報(bào)文, UDP 原樣發(fā)送, 既不會(huì)拆分, 也不會(huì)合并。
用 UDP 傳輸 100 個(gè)字節(jié)的數(shù)據(jù):
如果發(fā)送端調(diào)用一次 sendto, 發(fā)送 100 個(gè)字節(jié), 那么接收端也必須調(diào)用對應(yīng)的 一次 recvfrom, 接收 100 個(gè)字節(jié); 而不能循環(huán)調(diào)用 10 次 recvfrom, 每次接收 10 個(gè)字 節(jié);
UDP的緩沖區(qū):
UDP 沒有真正意義上的 發(fā)送緩沖區(qū)。?調(diào)用 sendto 會(huì)直接交給內(nèi)核, 由內(nèi)核將數(shù)據(jù)傳給網(wǎng)絡(luò)層協(xié)議進(jìn)行后續(xù)的傳輸動(dòng)作。UDP 具有接收緩沖區(qū)。?但是這個(gè)接收緩沖區(qū)不能保證收到的 UDP 報(bào)的順序和 發(fā)送 UDP 報(bào)的順序一致; 如果緩沖區(qū)滿了, 再到達(dá)的 UDP 數(shù)據(jù)就會(huì)被丟棄。UDP的socket既能讀,又能寫。這樣的特性叫做全雙工。
為什么UDP要有接收緩沖區(qū)?
如果UDP沒有接收緩沖區(qū),那么就要求上層及時(shí)將UDP獲取到的報(bào)文讀取上去,如果一個(gè)報(bào)文在UDP沒有被讀取,那么此時(shí)UDP從底層獲取上來的報(bào)文數(shù)據(jù)就會(huì)被迫丟棄。
一個(gè)報(bào)文從一臺(tái)主機(jī)傳輸?shù)搅硪慌_(tái)主機(jī),在傳輸過程中會(huì)消耗主機(jī)資源和網(wǎng)絡(luò)資源。如果UDP收到一個(gè)報(bào)文后僅僅因?yàn)樯洗问盏降膱?bào)文沒有被上層讀取,而被迫丟棄一個(gè)可能并沒有錯(cuò)誤的報(bào)文,這就是在浪費(fèi)主機(jī)資源和網(wǎng)絡(luò)資源。
因此UDP本身是會(huì)維護(hù)一個(gè)接收緩沖區(qū)的,當(dāng)有新的UDP報(bào)文到來時(shí)就會(huì)把這個(gè)報(bào)文放到接收緩沖區(qū)當(dāng)中,此時(shí)上層在讀數(shù)據(jù)的時(shí)候就直接從這個(gè)接收緩沖區(qū)當(dāng)中進(jìn)行讀取就行了,而如果UDP接收緩沖區(qū)當(dāng)中沒有數(shù)據(jù)那上層在讀取時(shí)就會(huì)被阻塞。因此UDP的接收緩沖區(qū)的作用就是,將接收到的報(bào)文暫時(shí)的保存起來,供上層讀取。
UDP使用注意事項(xiàng):
我們注意到, UDP 協(xié)議首部中有一個(gè) 16 位的最大長度。?也就是說一個(gè) UDP 能傳輸?shù)臄?shù)據(jù)最大長度是 64K(包含 UDP 首部)。
然而 64K 在當(dāng)今的互聯(lián)網(wǎng)環(huán)境下, 是一個(gè)非常小的數(shù)字。
如果我們需要傳輸?shù)臄?shù)據(jù)超過 64K, 就需要在應(yīng)用層手動(dòng)的分包, 多次發(fā)送, 并在接收端 手動(dòng)拼裝;
基于UDP的應(yīng)用層協(xié)議:
NFS: 網(wǎng)絡(luò)文件系統(tǒng)TFTP: 簡單文件傳輸協(xié)議DHCP: 動(dòng)態(tài)主機(jī)配置協(xié)議BOOTP: 啟動(dòng)協(xié)議(用于無盤設(shè)備啟動(dòng))DNS: 域名解析協(xié)議
當(dāng)然, 也包括你自己寫 UDP 程序時(shí)自定義的應(yīng)用層協(xié)議。
總結(jié):
好了,到這里今天的知識(shí)就講完了,大家有錯(cuò)誤一點(diǎn)要在評論指出,我怕我一人擱這瞎bb,沒人告訴我錯(cuò)誤就寄了。
祝大家越來越好,不用關(guān)注我(瘋狂暗示)
柚子快報(bào)邀請碼778899分享:網(wǎng)絡(luò) 傳輸層協(xié)議UDP詳解
相關(guān)文章
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。