【計算機網絡】傳輸層UDP協議

🔥個人主頁🔥:孤寂大仙V
🌈收錄專欄🌈:計算機網絡
🌹往期回顧🌹: 【計算機網絡】應用層協議Http——構建Http服務服務器
🔖流水不爭,爭的是滔滔不息


  • 一、UDP協議
  • 二、UDP特點
    • 面向數據報
  • 三、UDP緩沖區
  • 四、基于UDP的應用層協議
  • 五、報文理解

一、UDP協議

UDP(User Datagram Protocol,用戶數據報協議)是一種無連接的傳輸層協議,提供簡單的、不可靠的數據傳輸服務。與TCP不同,UDP不保證數據包的順序、可靠性或流量控制,但具有低延遲和高效率的特點,適用于實時性要求高但允許少量丟包的應用場景。

UDP協議端格式
在這里插入圖片描述
UDP 報文其實很簡單,它的格式是 “定長報頭 + 不定長數據”。如圖上面8字節是報頭大小,下面數據是有效載荷。UDP報頭是定長報頭,所以每個報文交付給上層報頭都是確定的。UDP報文分離的時候,直接把定長的報頭和有效載荷分離就好了,分用根據目的端口號去完成。UDP報文和報文之間都有有邊界的,所以不用像TCP傳輸那樣還要自定義協議區區分報頭。16位源端口號是表示報文是從哪發的,16位目的端口號是表示報文要發到哪里。端口號設計為16位的,是因為內核協議是16位的。報頭是固定的,每個報文的有效載荷能和報頭分明的區分,且報文和報文之間有邊界,這就是用戶數據報最大的特點。16 位 UDP 長度, 表示整個數據報(UDP 首部+UDP 數據)的最大長度;如果校驗和出錯, 就會直接丟棄;

為什么說UDP簡單?
UDP和TCP有一個最大的不同:UDP是有“邊界”的協議,每一個UDP報文本身就是獨立的一塊
內核收到一個UDP報文,直接把8字節頭部剝掉,剩下的數據送到應用層就行。
每一個recvfrom()調用,只會收到一個完整的UDP報文(不會拆開,也不會合并)。
不像TCP:TCP是“流”,沒有邊界,一個包可能拆成多個recv才收完,或者多個包粘在一起。所以TCP應用層必須“自己想辦法分包”,比如用自定義協議。

二、UDP特點

UDP 傳輸的過程類似于寄信。

  • 無連接: 知道對端的 IP 和端口號就直接進行傳輸, 不需要建立連接;
  • 不可靠: 沒有確認機制, 沒有重傳機制; 如果因為網絡故障該段無法發到對方,UDP 協議層也不會給應用層返回任何錯誤信息;
  • 面向數據報: 不能夠靈活的控制讀寫數據的次數和數量;

面向數據報

應用層交給 UDP 多長的報文, UDP 原樣發送, 既不會拆分, 也不會合并;
用 UDP 傳輸 100 個字節的數據:如果發送端調用一次 sendto, 發送 100 個字節, 那么接收端也必須調用對應的一次 recvfrom, 接收 100 個字節; 而不能循環調用 10 次 recvfrom, 每次接收 10 個字節。

三、UDP緩沖區

在這里插入圖片描述
UDP 沒有真正意義上的 發送緩沖區. 調用 sendto 會直接交給內核, 由內核將數據傳給網絡層協議進行后續的傳輸動作;
UDP 具有接收緩沖區. 但是這個接收緩沖區不能保證收到的 UDP 報的順序和發送 UDP 報的順序一致; 如果緩沖區滿了, 再到達的 UDP 數據就會被丟棄;
UDP 的 socket 既能讀, 也能寫, 這個概念叫做 全雙工

因為UDP沒有發送緩沖區,所以如果報文在網絡傳輸的過程中丟包了,UDP 本身是“無連接 + 不可靠傳輸協議”,它不會確認你發出去了沒,也不會重傳,如果在網絡中丟了,那就真的丟了,服務器一無所知。

如果應用層正在進行報文的解析,不會影響OS從網絡中讀取報文

UDP使用注意事項
我們注意到, UDP 協議首部中有一個 16 位的最大長度. 也就是說一個 UDP 能傳輸的數據最大長度是 64K(包含 UDP 首部).。
然而 64K 在當今的互聯網環境下, 是一個非常小的數字,如果我們需要傳輸的數據超過 64K, 就需要在應用層手動的分包, 多次發送, 并在接收端手動拼裝。

四、基于UDP的應用層協議

  • DNS(Domain Name System)
    DNS用于將域名解析為IP地址。由于查詢通常只需一次請求-響應,UDP的輕量特性使其成為首選。默認使用端口53。
  • DHCP(Dynamic Host Configuration Protocol)
    DHCP用于自動分配IP地址。UDP的廣播和多播支持使其適合局域網內的地址分配。客戶端使用端口68,服務器使用端口67。
  • SNMP(Simple Network Management Protocol)
    SNMP用于網絡設備監控和管理。UDP的簡單性適合頻繁的監控數據交換。默認使用端口161(查詢)和162(陷阱)。
  • TFTP(Trivial File Transfer Protocol)
    TFTP是簡單的文件傳輸協議,常用于網絡引導或設備固件更新。使用UDP端口69,實現比FTP更輕量。
  • QUIC(Quick UDP Internet Connections)
    QUIC是Google開發的傳輸協議,基于UDP實現類似TCP的可靠性,但減少握手延遲。HTTP/3基于QUIC,提升Web性能。
  • VoIP(Voice over IP)
    語音通話協議如RTP(Real-time Transport Protocol)通常基于UDP。實時性要求高,少量丟包對語音質量影響較小。

五、報文理解

Linux sk_buff源碼

struct sk_buff {union {struct {struct sk_buff *next;struct sk_buff *prev;union {struct net_device *dev;unsigned long dev_scratch;};};struct rb_node rbnode; // 用于紅黑樹};union {struct sock *sk;int ip_defrag_offset;};char cb[48]; // 控制緩沖區,協議層私有數據unsigned long _skb_refdst;unsigned int len, data_len;__u16 mac_len, hdr_len;__u16 queue_mapping;__u8 cloned:1, nohdr:1, fclone:2, peeked:1, head_frag:1;__u8 pfmemalloc:1, pp_recycle:1;__u16 tc_index; // 流量控制索引__u16 transport_header;__u16 network_header;__u16 mac_header;__u32 headers_end[0];void (*destructor)(struct sk_buff *skb);struct nf_conntrack *nfct;unsigned long nfct_reasm;__u32 secmark;unsigned int mark;__u16 vlan_proto;__u16 vlan_tci;union {__u32 inner_network_header;__u32 inner_network_header_offset;};__u32 inner_transport_header;__be16 protocol;__u16 transport_header_was;__u8 encapsulation:1;// 更多字段...unsigned char *head, *data, *tail, *end;
};

在這里插入圖片描述
在操作系統內部,可能會同時存在大量的報文,操作系統必須管理這些報文。引入sk_buff(Socket Buffer)是 Linux 內核網絡協議棧中 收發數據的核心結構體,每當有網絡數據要處理,內核就會分配一個 sk_buff。

skb->head, skb->data, skb->tail, skb->end 是sk_buff內的指針。

  • skb->head:指向整個緩沖區的起始位置(分配的整塊內存)
  • skb->data:指向有效數據的起始位置(比如 IP 頭部開始)
  • skb->tail:指向有效數據的結尾(可以向后追加數據)
  • skb->end:指向緩沖區結尾(表示最多能寫到哪)

所謂封裝和解包,本質就是移動data指針在緩沖區中指向。

我們把data和tail想成一個"動態窗口",當我們的報完往下層協議封裝就要往前移動data指針,封裝報頭,當往后移動tail指針的時候是添加新的數據。


發送過程:從上層到下層
調用send()或者write()發送數據,數據經歷了用戶態->內核態->網絡層多次加工封裝。
發送數據,數據進入內核socket buffer,內核分配sk_buff,并把數據填進去(通常從skb->tail開始)。進去TCP層,加上TCP報頭skb->tail往前移動數據跟在TCP頭后面,設置TCP序號、校驗和等。進入IP層。加上IP層報頭,設置源IP、目的IP等。進入數據鏈路層加MAC頭,設置目標MAC、源MAC等。最后整個數據包都集中在skb->data和skb->tail之間->DMA拷貝給網卡發送過去。
接收過程:從底層到上層
網卡收到數據,觸發中斷。驅動將數據拷貝到sk_buff。skb->data指向以太網頭部。一層一層"剝皮"去掉報頭。最后skb->data指向payload(應用層數據)上交給socket buffer,再wake up用戶進程接收。

sk_buff 就是內核網絡協議棧用來“托運數據”的容器,skb->data 是快遞包裹的“當前開箱點”,從 TCP 到 IP 到 MAC,每一層往前預留一段頭,然后下發出去。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/85761.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/85761.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/85761.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

「Java教案」順序結構

課程目標 1.知識目標 能夠正確使用Java順序結構的基本語法,例如變量的聲明、變量的賦值、表達式的計算、數據的輸出。能夠正確使用順序結構的執行規則及其在程序中的作用,解決實際問題。 2.能力目標 能夠獨立完成順序結構程序…

第八部分:階段項目 6:構建 React 前端應用

現在,是時候將你學到的 React 基礎知識付諸實踐,構建一個簡單的前端應用來模擬與后端 API 的交互了。在這個階段,你可以先使用模擬數據,或者如果你的后端 API(階段項目 5)已經搭建好,可以直接連…

GO語言----基礎類型取別名

文章目錄 取別名示例注意事項 Go語言中使用type關鍵字為基礎類型取別名。 type是Go語言中用于定義新類型的關鍵字,它提供了強大的類型定義能力。 取別名示例 type MyInt int注意事項 這創建了一個新類型MyInt,它底層是int類型,但與int是不同…

服務端定時器的學習(一)

一、定時器 1、定時器是什么? 定時器不僅存在于硬件領域,在軟件層面(客戶端、網頁和服務端)也普遍應用,核心功能都是高效管理大量延時任務。不同應用場景下,其實現方式和使用方法有所差異。 2、定時器解…

Mac版本Android Studio配置LeetCode插件

第一步:Android Studio里面找到Settings,找到Plugins,在Marketplace里面搜索LeetCode Editor。 第二步:安裝對應插件,并在Tools->LeetCode Plugin頁面輸入帳號和密碼。 理論上,應該就可以使用了。但是&a…

【ISP算法精粹】動手實戰:用 Python 實現 Bayer 圖像的黑電平校正

在數字成像領域,圖像信號處理器(ISP)如同幕后英雄,默默將傳感器捕獲的原始數據轉化為精美的圖像。而黑電平校正,作為ISP預處理流程中的關鍵一環,直接影響著最終圖像的質量。今天,我們就通過Pyth…

Oracle OCP與MySQL OCP認證如何選?

認證本質與定位差異 Oracle OCP Oracle OCP是Oracle公司推出的旗艦級數據庫專家認證,專注于其核心的閉源商業數據庫技術體系。核心領域包括RAC(Real Application Clusters)高可用集群、Data Guard容災解決方案、Exadata數據庫一體機集成以及…

MVVM、MVC的區別、什么是MVVM

一、什么是MVVM (一)定義 MVVM是Model - View - ViewModel的縮寫,它是一種軟件架構設計模式,主要用于構建用戶界面。這種模式將應用程序分為三個主要部分: Model(模型層) 它是應用程序中負責…

【SpringCache 提供的一套基于注解的緩存抽象機制】

Spring 緩存(Spring Cache)是 Spring 提供的一套基于注解的緩存抽象機制,常用于提升系統性能、減少重復查詢數據庫或接口調用。 ? 一、基本原理 Spring Cache 通過對方法的返回結果進行緩存,后續相同參數的調用將直接從緩存中讀…

HRI-2025 | 大模型驅動的個性化可解釋機器人人機交互研究

作者:Ferran Gebelli 1 ^{1} 1, Lavinia Hriscu 2 ^{2} 2, Raquel Ros 1 ^{1} 1, Sverin Lemaignan 1 ^{1} 1, Alberto Sanfeliu 2 ^{2} 2, Anais Garrell 2 ^{2} 2單位: 1 ^{1} 1PAL Robotics, 2 ^{2} 2IRI (UPC-CSIC)論文標題:P…

Gitee Wiki:重塑關鍵領域軟件研發的知識管理范式

在數字化轉型浪潮席卷全球的當下,關鍵領域軟件研發正面臨前所未有的知識管理挑戰。傳統文檔管理模式的局限性日益凸顯,知識傳承的斷層問題愈發嚴重,團隊協作效率的瓶頸亟待突破。Gitee Wiki作為新一代知識管理平臺,正在通過技術創…

JVM 內存溢出 詳解

內存溢出 內存溢出指的是內存中某一塊區域的使用量超過了允許使用的最大值,從而使用內存時因空間不足而失敗,虛擬機一般會拋出指定的錯誤。 在Java虛擬機中,只有程序計數器不會出現內存溢出的情況,因為每個線程的程序計數器只保…

dvwa8——SQL Injection(Blind)

由題目得這一關用盲注寫 LOW: 先用bp抓包一下 , 看到這low是get提交 , f12打開hackbar 輸入?id1時報錯 嘗試閉合 , 回顯正常 開始注入 1.order by 判斷列數,3的時候開始回顯報錯,所以有兩列 ?id1 order by 2--&SubmitSubmit# 2.無回顯位置可以爆出,我們通過盲注來繼…

探索分布式存儲與通信:去中心化共享及通訊(DSAC)

在當今數字化時代,分布式系統的重要性愈發凸顯。它不僅能提升數據的存儲安全性和可靠性,還能增強通信的效率和隱私性。于是我做了這個去中心化共享及通訊的程序,它構建了一個強大的分布式存儲和通信網絡,下面我們就來詳細了解其實…

ass字幕嵌入mp4帶偏移

# 格式轉化文件,包含多種文件的互相轉化,主要與視頻相關 from pathlib import Path import subprocess import random import os import reclass Utils(object):staticmethoddef get_decimal_part(x: float) -> float:s format(x, .15f) # 格式化為…

05 APP 自動化- Appium 單點觸控 多點觸控

文章目錄 一、單點觸控查看指針的指針位置實現手勢密碼: 二、多點觸控 一、單點觸控 查看指針的指針位置 方便查看手勢密碼-九宮格每個點的坐標 實現手勢密碼: 執行手勢操作: 按壓起點 -> 移動到下一點 -> 依次移動 -> 釋放&am…

【軟件】在 macOS 上安裝 MySQL

在 macOS 上安裝 MySQL 有多種方法,以下是兩種常見的安裝方式:通過 Homebrew 安裝和通過安裝包安裝。以下是詳細的步驟: 一、通過 Homebrew 安裝 MySQL Homebrew 是 macOS 的包管理器,使用它安裝 MySQL 非常方便。 1.安裝 Home…

第11節 Node.js 模塊系統

為了讓Node.js的文件可以相互調用,Node.js提供了一個簡單的模塊系統。 模塊是Node.js 應用程序的基本組成部分,文件和模塊是一一對應的。換言之,一個 Node.js 文件就是一個模塊,這個文件可能是JavaScript 代碼、JSON 或者編譯過的…

力扣熱題100之二叉樹的直徑

題目 給你一棵二叉樹的根節點,返回該樹的 直徑 。 二叉樹的 直徑 是指樹中任意兩個節點之間最長路徑的 長度 。這條路徑可能經過也可能不經過根節點 root 。 兩節點之間路徑的 長度 由它們之間邊數表示。 代碼 方法:遞歸 計算二叉樹的直徑可以理解…

OpenCV CUDA模塊圖像處理------創建CUDA加速的Canny邊緣檢測器對象createCannyEdgeDetector()

操作系統:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 編程語言:C11 算法描述 該函數用于創建一個 CUDA 加速的 Canny 邊緣檢測器對象(CannyEdgeDetector),可以在 GPU 上高效執行 Canny 邊…