【Linux网络】传输层协议UDP

目录

一、前言

二、网络分层与端口号基础

[三、UDP 报文格式](#三、UDP 报文格式)

[四、UDP 封装与解包原理](#四、UDP 封装与解包原理)

[五、内核视角:UDP 报文封装过程](#五、内核视角:UDP 报文封装过程)

​编辑

[六、UDP 核心特点](#六、UDP 核心特点)

[七、UDP 缓冲区机制](#七、UDP 缓冲区机制)

[八、UDP 报文大小限制](#八、UDP 报文大小限制)

[九、UDP 适用场景](#九、UDP 适用场景)


一、前言

我们在学习协议的时候,是从应用层自顶向下学习的;今天学习传输层的UDP协议

在计算机网络传输层中,最核心的两大协议就是 TCP 和 UDP。相比于复杂严谨的 TCP,UDP 更加轻量、简单。很多应用层协议如 DNS、直播、音视频通话、游戏联机等,底层都默认使用 UDP 协议。今天我们结合网络原理底层知识,完整梳理 UDP 协议的所有核心知识点。

二、网络分层与端口号基础

网络通信的本质,其实并不是"主机与主机之间通信",而是"主机上的进程与进程之间通信"。

在网络中,真正进行数据收发的是运行中的应用程序(进程),而不是计算机本身。

因此,想要在网络中唯一标识一个通信进程,需要依靠:

  • IP 地址:用于定位网络中的主机

  • 端口号(Port):用于定位主机中的具体进程

二者组合在一起,就构成了 Socket(套接字)

而想要唯一标识一次完整的网络通信,则需要依靠"四元组":源 IP,源端口,目的 IP,目的端口

也就是说,网络中的每一次连接,本质上都是两个 Socket 之间的通信。

端口号的范围划分

1. 0 ~ 1023:知名端口号(Well-Known Port)

这一类端口号专门留给标准的应用层协议使用,例如:

HTTP:80 HTTPS:443 FTP:21 SSH:22 SMTP:25

这些端口都是行业内约定俗成的固定端口,不能随意修改。

可以把它理解成现实生活中的"特殊号码":

110 → 报警

119 → 消防

120 → 急救

用户只需要记住号码,就能找到对应服务。

网络中的知名端口也是同样的道理------客户端通过固定端口,就能快速定位对应的网络服务。

2. 1024 ~ 65535:动态 / 临时端口号

这一部分端口通常由操作系统自动分配给客户端程序使用。

当客户端发起网络请求时,操作系统会从这个区间中临时随机选择一个空闲端口,作为当前连接的源端口。

通信结束后,该端口会被释放,供后续程序继续使用。

端口与进程绑定的两个核心问题

一个进程可以绑定多个端口号吗?

可以。一个进程本质上可以同时提供多个网络服务,因此能够绑定多个端口。

一个端口号可以被多个进程同时绑定吗?

通常不可以

因为端口号的核心作用,就是在主机中唯一标识一个网络进程。

如果多个进程同时绑定同一个端口,操作系统就无法判断:

"收到的数据到底应该交给哪个进程处理?"

因此,同一时刻,一个端口通常只能被一个进程占用。

三、UDP 报文格式

UDP协议的格式:

这里的数据指的是应用层(上一层)传输给传输层的数据;数据有可能是网络版本的计算器,request,response,string

字段 大小 作用
源端口号 16 位 标识发送方进程
目的端口号 16 位 标识接收方主机中的目标进程
UDP 长度 16 位 表示整个 UDP 报文的长度(首部 + 数据)
UDP 校验和 16 位 用于校验数据完整性,检测传输过程中是否出现比特错误

我们来解释一下每个部分:
(1)源端口号

用于标识数据从哪个进程发送出来。

当服务器收到数据后,可以根据该端口号知道:

"应该把响应数据返回给客户端的哪个进程。

(2)目的端口号

用于告诉目标主机:"这个 UDP 数据应该交给哪个应用程序处理。

操作系统收到 UDP 报文后,会根据目的端口号进行分用,找到对应进程

(3) UDP 长度

表示整个 UDP 报文的总长度:

UDP 长度 = UDP 首部 + 应用层数据

由于 UDP 首部固定为 8 字节,因此:
UDP 长度 = 8 + Data

这个字段可以帮助接收方正确提取数据边界

(4)UDP 校验和

用于检测数据在传输过程中是否发生错误。

发送方会根据 UDP 数据计算出一个校验值,接收方收到后再次计算:

• 如果结果一致 → 数据正常

• 如果结果不一致 → 数据可能损坏
UDP 只能"发现错误",但不会像 TCP 一样自动重传数据。

报文·完整是报头+有效载荷,我们更多谈的是报头

从代码层面看,UDP 报头本质就是内核中的一个结构体

cpp 复制代码
struct udphdr{
    _be16 source;   // 源端口
    _be16 dest;     // 目的端口
    _be16 len;      // UDP长度
    _sum16 check;   // 校验和
};

操作系统通信时无需额外序列化,可直接将结构体报头封装发送,保证内核通信效率。

四、UDP 封装与解包原理

1. 报头与有效载荷分离

UDP 采用定长报头设计,固定 8 字节。

内核读取报文时,直接前 8 字节作为 UDP 首部,剩余部分全部作为应用层有效载荷,分离逻辑简单高效。
2. 分用机制

UDP中包含16位源端口号,16位目的端口号; 根据目的端口号将有效载荷交给目标进程

依靠报文里的目的端口号,内核把解析出的有效载荷,精准交付给对应的应用进程。
3. 无粘包问题

UDP 自身携带 16 位长度字段,内核明确知道每一个 UDP 报文的边界和大小。

报文之间相互独立,一个一个向上交付数据,因此 UDP 不存在粘包问题,属于面向数据包的协议。
4. UDP 校验和作用

以特定算法校验整个报文,保证传输过程中比特位不发生错误。

校验失败:报文直接丢弃,不向上层通知错误

校验成功:正常交付给应用进程

这也体现了 UDP 不可靠的特性。

五、内核视角:UDP 报文封装过程

但网卡不能直接发送数据

因为网络通信必须带:MAC 地址;IP 地址;端口号;校验信息

所以操作系统必须:

  1. 先管理数据
  2. 再逐层添加协议头
  3. 最后交给网卡发送

这就叫:UDP 封装

操作系统内核收到大量网络报文,遵循先描述、再组织的原则管理报文。

内核会创建 sk_buff 内核缓冲区结构体,划分出头空间、二层帧头、IP 头、传输层协议头、数据区、尾空间。

通过移动 data 指针开辟报头空间,使用 C 语言指针和内存拷贝完成协议首部封装,最终将完整报文向下交付给网络层发送。

UDP 封装本质不是:

复制代码
"往后拼接"

而是:"data 指针不断向前移动,预留并填写协议头"

六、UDP 核心特点

UDP 传输过程可以形象理解为寄平信、发快递,核心四大特点:
1. 无连接

只需知道对方的 IP + 端口,直接发送数据,不需要提前建立连接,省去握手开销,速度极快。
2. 不可靠

无确认应答、无超时重传机制。

如果网络丢包、路由故障导致数据无法到达对方,UDP 不会重传,也不会给应用层返回任何错误提示,发出去就不管了。

注意:可靠与不可靠只是协议特点,不是优缺点,不同场景各有适用。
3. 面向数据报

应用层交给 UDP 多大的报文,UDP 就原样发送,不拆分、不合并。

发送端一次 sendto 发 100 字节,接收端必须一次 recvfrom 收 100 字节

不能拆分多次接收,收发次数完全对等

这和 TCP 面向字节流、收发次数不一致形成鲜明对比。
4. 全双工通信

UDP 的 Socket 既可以读数据,也可以写数据,支持同时收发,属于全双工模式。

七、UDP 缓冲区机制

无真正发送缓冲区

调用 sendto 发送数据时,数据直接交给内核,内核向下交付网络层直接发送。

因为 UDP 无需等待应答、不用保存已发数据,所以不需要发送缓冲区。

UDP是没有后续动作的,它发送出去的数据是不管数据有没有丢包,直接交给操作系统,所以就不需要保存数据,就没有发送缓冲区

先发送的报文一定先被操作系统接收吗?不一定

就像你和你的朋友先后去北京;你朋友先骑车去,你后去但是是做飞机去

有接收缓冲区

内核维护 UDP 接收缓冲区,但不保证报文按发送顺序到达,网络路由不同会导致报文乱序。

若缓冲区已满,后续到达的 UDP 报文会直接被丢弃。

八、UDP 报文大小限制

单个 UDP 报文最大不能超过 64KB

如果应用层需要传输超过 64KB 的数据,UDP 协议本身不支持拆分重组,需要程序员手动对数据分块发送,接收端再手动拼接。

九、UDP 适用场景

基于 UDP 无连接、速度快、面向数据报、允许少量丢包的特性,适合这些场景:

音视频直播、短视频、实时通话

网络游戏联机

DNS 域名解析

广播、组播通信

这类场景都能容忍少量丢包,但对实时性要求极高,正好契合 UDP 的设计理念。

相关推荐
影寂ldy1 小时前
C#数组的高级方法
开发语言·c#
Tisfy1 小时前
LeetCode 3121.统计特殊字母的数量 II:状态机
算法·leetcode·题解·状态机
星恒讯工业路由器1 小时前
WiFi 安全技术演进全解析:从 WEP 到 WPA3 的迭代与安全蜕变
网络·安全·wifi·信息与通信
中基数联软件造价1 小时前
第三方软件造价评估服务如何助力政务信息化合规?辽宁新规提供政策依据
网络·数据库·政务
格发许可优化管理系统1 小时前
解决Mentor许可冲突,让您的业务无缝运行
运维·服务器·c语言·c++·人工智能
洛水水1 小时前
【力扣100题】61.和为 K 的子数组
算法·leetcode·哈希算法
上海云盾-小余1 小时前
服务器入侵应急处置:入侵排查与溯源恢复全流程
运维·服务器·github
曹牧2 小时前
C#:基类中定义泛型方法
java·开发语言·c#
游乐码2 小时前
c#基础(七)延迟函数
开发语言·unity·c#·游戏引擎