传输层协议之UDP
一、传输层与端口号
1.1 传输层的作用
在 TCP/IP 网络体系结构中,传输层(Transport Layer)位于应用层与网络层之间,主要负责为不同主机上的应用程序提供端到端的数据传输服务。

网络层通过 IP 地址实现主机之间的数据传输,而传输层则需要进一步解决一个问题:当数据到达目标主机后,操作系统应当将其交给哪个进程(网络通信本质是进程间通信)?
为解决这一问题,传输层引入了端口号(Port)的概念。
1.2 端口号
端口号用于标识主机上的通信端点,使操作系统能够将接收到的数据交付给对应的 Socket。
TCP 和 UDP 的端口号均由 16 位无符号整数表示,因此其取值范围为:
-
0~1023:知名端口号(Well-Known Ports),通常分配给广泛使用的网络服务。
-
1024~65535:其他端口号,其中一部分用于注册服务,另一部分可由操作系统动态分配给客户端程序。
IANA 将端口划分为知名端口(0~1023)、注册端口(1024~49151)和动态或私有端口(49152~65535)。操作系统实际使用的临时端口范围可以不同。
常见服务的默认端口如下:
| 服务 | 默认端口号 | 传输层协议 |
|---|---|---|
| FTP | 21 | TCP |
| SSH | 22 | TCP |
| Telnet | 23 | TCP |
| SMTP | 25 | TCP |
| DNS | 53 | UDP/TCP |
| HTTP | 80 | TCP |
| HTTPS | 443 | TCP(HTTP/3 使用 UDP) |
在 Linux 系统中,可以通过以下命令查看系统维护的服务端口映射信息:
cat /etc/services
也可以通过以下命令查看当前正在监听的 UDP Socket:
ss -lunp
需要注意,端口号并不等同于进程 ID。一个进程可以创建多个 Socket,并绑定不同的端口;一个端口也不一定只能被一个进程使用,实际绑定行为取决于本地 IP 地址、传输层协议及端口复用选项等条件。
1.3 TCP/IP 五元组
在网络通信过程中,通常使用五元组描述一条通信流:
源 IP 地址、源端口号、目的 IP 地址、目的端口号、协议号。
例如,某客户端通过 UDP 向 DNS 服务器发送请求:
| 五元组字段 | 示例 |
|---|---|
| 源 IP | 192.168.1.10 |
| 源端口 | 50000 |
| 目的 IP | 192.168.1.20 |
| 目的端口 | 53 |
| 协议号 | 17(UDP) |
五元组中的 IP 地址由网络层提供,端口号由传输层提供。对于 IPv4,协议号存储在 IP 首部的 Protocol 字段中,其中 TCP 对应 6,UDP 对应 17。
因此,UDP 首部中虽然没有源 IP 和目的 IP,但 UDP 数据报会被封装在 IP 数据包中进行传输。IP 层负责定位主机,UDP 层负责区分主机上的通信端点。
二、UDP 协议及其报文格式
UDP(User Datagram Protocol,用户数据报协议)是 TCP/IP 体系结构中的一种传输层协议。
与 TCP 不同,UDP 不需要在通信前建立连接,也不提供 TCP 所具有的确认应答、超时重传、按序交付等可靠性机制。
UDP 的协议结构相对简单,首部开销较小,因此适合对实时性要求较高,或者由应用层自行实现可靠性机制的通信场景。
2.1 UDP 报文结构
一个 UDP 数据报由 UDP 首部和数据部分组成。
UDP 首部固定为 8 字节,包含四个字段,每个字段均占 16 位。

| 字段 | 长度 | 作用 |
|---|---|---|
| 源端口号 | 16 bit | 标识发送端端口 |
| 目的端口号 | 16 bit | 标识接收端端口 |
| UDP 长度 | 16 bit | 表示 UDP 首部与数据的总长度 |
| UDP 校验和 | 16 bit | 检测数据报在传输过程中是否出现差错 |
其中:
(1)源端口号和目的端口号
源端口号用于标识发送方的通信端口,目的端口号用于标识接收方的通信端口。
当 UDP 数据报到达目标主机后,操作系统根据目的端口等信息,将数据交付给对应的 Socket。
(2)UDP 长度
UDP 长度字段表示 UDP 首部与 UDP 数据部分的总长度。
例如,若应用层发送了 100 字节的数据:
UDP长度=8+100=108字节
由于该字段只有 16 位,因此普通 UDP 数据报的长度字段最大能够表示 65535 字节。
(3)UDP 校验和
UDP 校验和用于检测数据传输过程中可能发生的比特错误。
计算 UDP 校验和时,除了 UDP 首部和数据,还会使用包含源 IP、目的 IP 等信息的伪首部。伪首部只参与校验和计算,并不实际存储在 UDP 首部中。
在 IPv4 中,UDP 校验和可以不启用;在一般 IPv6 UDP 通信中,校验和是必需的。如果接收方发现已启用的校验和验证失败,通常会丢弃该数据报。
三、UDP 协议的主要特点
UDP 具有无连接、不可靠和面向数据报三个核心特点。
3.1 无连接
UDP 是一种无连接的传输层协议。
发送方只需要知道接收方的 IP 地址和端口号,就可以尝试向对方发送数据,而不需要像 TCP 那样先通过三次握手建立连接。
例如,在 Linux 网络编程中,可以通过 sendto() 向指定的地址发送 UDP 数据报:
sendto(sockfd, buffer, len, 0,(struct sockaddr*)&server, sizeof(server));
UDP 不需要建立连接,因此减少了连接建立过程带来的额外开销。
UDP Socket 也可以调用 connect(),但这只是为 Socket 设置默认通信对端,并不意味着 UDP 建立了 TCP 意义上的可靠连接。
3.2 不可靠
UDP 不提供可靠传输保证,主要表现在:
- 不保证数据一定能够到达接收方。
- 不保证多个数据报按照发送顺序到达。
- 不提供协议层面的确认应答与自动重传。
- 不保证每个数据报只被交付一次。
例如,发送方连续发送三个 UDP 数据报:
发送方:A → B → C
接收方:A → C
由于网络拥塞、设备故障等原因,数据报 B 可能在传输过程中丢失。
UDP 本身不会自动重新发送 B,也不会要求接收方确认每个数据报已经成功到达。
不过,这并不意味着 sendto() 不会返回错误。系统仍然可能报告本地发送失败或部分网络错误,只是 UDP 不提供 TCP 式的可靠交付机制。
如果应用程序需要可靠传输,可以在应用层设计序列号、确认应答、超时重传等机制。
3.3 面向数据报
UDP 是一种面向数据报的协议,其重要特点是保留应用层消息的边界。
假设发送方调用两次 sendto():
sendto(..., 100, ...);
sendto(..., 200, ...);
分别发送 100 字节和 200 字节的数据。
在两个数据报均成功到达的情况下,接收方需要通过对应的数据报接收操作分别读取它们,而不会像 TCP 字节流那样将两个消息直接视为连续的 300 字节数据。
但是需要注意:
如果某个 UDP 数据报包含 100 字节,而接收方的缓冲区 只有 10 字节,那么普通的 recvfrom() 调用可能只返回前 10 字节,其余部分会被截断丢弃。
接收方不能通过再调用九次 recvfrom() 来读取原数据报剩余的 90 字节。
因此,在 UDP 网络编程中,应当合理设计数据报大小,并保证接收缓冲区能够容纳预期的数据报。
四、UDP 的缓冲区与使用限制
4.1 UDP 的发送与接收缓冲区
UDP 与 TCP 在数据缓冲机制上存在明显区别。
UDP 发送端:
UDP 不具有 TCP 那种用于维护可靠传输、确认及重传的数据缓存机制。
应用程序调用 sendto() 后,数据会交给操作系统内核,由内核协议栈进行后续处理。
但从 Linux 实现角度来说,UDP Socket 仍然涉及发送缓冲区及内核队列资源,不能将其理解为完全没有任何发送缓存。
UDP 接收端:
UDP Socket 具有接收缓冲区,用于暂存已经到达、尚未被应用程序读取的数据报。
如果应用程序读取速度较慢,接收缓冲区可能逐渐被填满。当缓冲区无法容纳新到达的数据报时,这些数据报就可能被丢弃。
另外,UDP 不保证数据报按发送顺序到达,接收缓冲区本身也不能弥补网络层面造成的乱序。
UDP Socket 同时支持发送和接收操作,因此可以进行全双工通信。
4.2 UDP 数据报的长度限制
UDP 首部中的长度字段为 16 位,能够表示的最大长度为:65535字节
由于 UDP 首部占据 8 字节,因此仅从 UDP 长度字段考虑,理论上最大数据部分为:
65535-8=65527字节
不过,数据还需要通过 IP 协议传输。
在普通 IPv4 数据包中,假设 IPv4 首部为 20 字节,则 UDP 应用层数据的最大长度通常为:
65535-20-8=65507字节
实际网络中的 MTU (最大传输单元)往往远小于这个值。例如,以太网常见 MTU 为 1500 字节。如果 UDP 数据报过大,可能发生 IP 分片,或者因路径 MTU 限制导致发送失败。
因此,应用程序一般应当避免发送过大的 UDP 数据报。
如果需要传输的数据超过单个数据报所能承载的长度,可以在应用层设计分包与重组机制,并根据需要增加序列号、丢包检测和重传机制。
五、基于 UDP 的应用层协议
UDP 结构简单、首部开销较小,适用于多种网络应用。
课件中列举了以下协议:
| 协议 | 全称 | 主要用途 |
|---|---|---|
| DNS | Domain Name System | 域名解析 |
| DHCP | Dynamic Host Configuration Protocol | 动态主机配置 |
| TFTP | Trivial File Transfer Protocol | 简单文件传输 |
| BOOTP | Bootstrap Protocol | 启动配置 |
| NFS | Network File System | 网络文件系统 |
需要注意,部分应用层协议并非只能使用 UDP。例如,DNS 也可以使用 TCP,NFS 的不同版本和部署方式也可以使用 TCP。
除此之外,UDP 还广泛应用于实时音视频、在线游戏、网络时间同步等场景。
这些应用通常比较关注通信时延,或者能够在应用层自行处理丢包、重传和数据恢复问题。
因此,选择 UDP 并不意味着应用程序完全不需要可靠性,而是将是否提供可靠性、如何实现可靠性交由具体的应用协议决定。
六、总结
UDP 是 TCP/IP 体系结构中一种重要的传输层协议,其主要特点可以概括为:
-
无连接: 发送数据前不需要通过三次握手建立连接。
-
不可靠: 不提供确认应答、自动重传和按序交付等可靠性保证。
-
面向数据报: 以独立数据报为单位进行发送和接收,保留消息边界。
-
首部开销较小: UDP 首部固定为 8 字节,包含源端口、目的端口、长度及校验和。
-
具有长度限制: 普通 UDP 数据报受协议长度字段和底层网络协议的共同限制。
与 TCP 相比,UDP 的协议机制较为简单,但可靠性保障也相对有限。
在实际网络编程中,应根据应用程序对可靠性、实时性、传输开销和消息边界的要求,合理选择 TCP 或 UDP。
UDP 的设计并不是单纯追求可靠传输,而是提供一种简单、低开销的数据报传输服务,将更复杂的可靠性控制交给有需要的应用层协议实现。