用户数据报协议 (UDP - User Datagram Protocol) 是互联网协议套件 (TCP/IP) 中位于传输层的一个简单而高效的协议。与复杂的 TCP 不同,UDP 提供了一种无连接 (Connectionless)不可靠 (Unreliable) 的数据报服务,强调传输速度和资源效率,而非数据的完整性和顺序性。它不对数据包进行排序、不保证送达、不进行错误重传、不提供流量控制和拥塞控制。

核心思想:UDP 就像邮局的平信服务。你把信投进去,邮局尽力送达,但不保证一定能送到,也不告诉你有没有送到。它不操心信的顺序,不提供回执,也不管你的信封里装了多少页纸。


一、UDP 的核心特性与设计哲学

UDP 的设计目标是提供一个最小化的传输层协议,只做传输层最基本的事情——多路复用和少量的错误校验。它将大部分的可靠性职责留给应用程序自行处理。

  1. 无连接 (Connectionless)

    • 在数据传输之前,通信双方无需建立或维护任何连接状态。
    • 发送方可以直接向目的端发送数据报。
    • 每个数据报都是独立的,包含完整的源地址和目的地址信息。
  2. 不可靠传输 (Unreliable Transmission)

    • UDP 不保证数据报的送达:数据报可能会丢失。
    • UDP 不保证数据报的顺序:数据报可能会乱序到达。
    • UDP 不提供错误重传机制:它不会检测数据包丢失并自动重传。
    • UDP 不进行流量控制:发送方发送多少数据,由应用程序决定,接收方可能来不及处理而丢弃。
    • UDP 不进行拥塞控制:它不会根据网络拥塞情况调整发送速率,可能会加剧网络拥塞。
  3. 基于数据报 (Datagram-Oriented)

    • UDP 传输的单位是数据报 (Datagram)
    • UDP 会保留应用程序发送的消息边界。即如果应用程序发送了两个独立的 UDP 数据报,接收方也会收到两个独立的数据报,而不是一个连续的字节流。这与 TCP 的字节流服务形成鲜明对比。
  4. 无状态 (Stateless)

    • 由于是无连接的,UDP 不维护任何关于对端或连接的状态信息。
    • 这种设计使得服务器可以同时处理大量客户端请求,无需为每个请求维护复杂的状态机。
  5. 头部开销小 (Small Header Overhead)

    • UDP 头部只有 8 字节,远小于 TCP 的 20 字节(不含选项)。
    • 这使得 UDP 传输单位数据量时效率更高。
  6. 全双工通信 (Full-Duplex Communication)

    • 虽然是无连接的,但 UDP 也是全双工的,通信双方可以独立地发送和接收数据报。

二、UDP 报文段结构

UDP 报文段,通常称为 UDP 数据报 (UDP Datagram),其头部非常简单,只有 8 字节。

1
2
3
4
5
6
7
8
9
+-------------------------------------------------------------+
| Source Port (16 bits) | Destination Port (16 bits) |
+-------------------------------------------------------------+
| Length (16 bits) | Checksum (16 bits) |
+-------------------------------------------------------------+
| |
| Data (Payload) |
| |
+-------------------------------------------------------------+

关键字段解释

  • 源端口 (Source Port) (16 位):
    • 标识发送 UDP 数据报的应用程序的端口号。如果不需要客户端的回复,源端口号可以置为 0。
  • 目的端口 (Destination Port) (16 位):
    • 标识接收 UDP 数据报的应用程序的端口号。
  • 长度 (Length) (16 位):
    • 整个 UDP 数据报的长度,包括 UDP 头部和数据部分。最小长度为 8 字节(只有头部),最大能表示 65535 字节。
  • 校验和 (Checksum) (16 位):
    • 用于检测 UDP 头部和数据部分的位错误。
    • 校验和的计算包括一个伪头部 (Pseudo-Header),伪头部是从 IP 头部中提取的一些字段(如源 IP 地址、目的 IP 地址、协议号等),不随 UDP 数据报一同传输,只用于校验和的计算。
    • UDP 校验和是可选的。在 IPv4 中,如果发送方不计算校验和,则该字段置为 0。在 IPv6 中,UDP 校验和是强制性的。
    • 如果校验和不匹配,接收方通常会丢弃该数据报。

三、UDP 数据传输过程

UDP 的数据传输过程极为简单:

关键点

  • 没有连接建立:直接发送数据。
  • 没有确认机制:发送方发送后不会等待接收方的确认。
  • 没有重传机制:如果数据报丢失,发送方不会自动重发。
  • 没有排队机制:如果数据报乱序到达,直接向上层应用程序提交,由应用程序处理乱序问题。
  • 消息边界保留:每个 sendto() 发送的数据报在接收端通过一个 recvfrom() 进行接收(前提是数据报未丢失)。

四、UDP 的优缺点与适用场景

4.1 优点:

  1. 开销小,效率高
    • 头部只有 8 字节,数据传输效率高。
    • 无需建立/维护连接,省去了三次握手和四次挥手的时间和资源开销。
  2. 传输速度快
    • 没有拥塞控制、流量控制和重传机制,传输延迟小,非常适合对实时性要求高的应用。
  3. 灵活控制
    • 应用程序可以完全控制数据的发送时机、是否重传、如何处理乱序等,提供了更大的灵活性。
  4. 一对多、多对一、多对多通信
    • UDP 支持广播 (Broadcast) 和多播 (Multicast),可以轻松实现一对多和多对多的通信模式。

4.2 缺点:

  1. 不可靠性
    • 数据报可能丢失、乱序、重复,且没有内置机制来保证数据的完整性。
  2. 无流量/拥塞控制
    • 发送方可能会以过快的速度发送数据,导致接收方缓冲区溢出而丢包,或加剧网络拥塞。
  3. 需要应用程序实现可靠性
    • 如果应用程序需要可靠传输,则必须在应用层自己实现确认、重传、排序、去重、流量控制等复杂逻辑,增加了开发难度。

4.3 适用场景:

  • 对实时性要求高、允许少量丢包的应用
    • 音视频通话 / 实时流媒体 (如 VoIP, 直播):允许偶尔的卡顿或丢帧,但不希望出现大的延迟。
    • 在线游戏:实时性是关键,即使有少量数据包丢失,也能通过游戏逻辑进行容忍或预测弥补。
  • 需要高效、低开销的通信
    • DNS (Domain Name System) 域名解析:通常使用 UDP 传输,请求-响应模型简单,一次查询只需要一个数据报。
    • SNMP (Simple Network Management Protocol) 网络管理协议:用于查询或设置网络设备状态,对可靠性要求不高。
    • DHCP (Dynamic Host Configuration Protocol):动态主机配置协议,用于 IP 地址分配。
  • 广播或多播通信
    • 局域网服务发现 (如 SSDP, mDNS)。
    • 视频会议
  • 某些自定义可靠传输协议的底层
    • 例如,Google 的 QUIC 协议(现在是 HTTP/3 的基础)就是在 UDP 之上构建的,它在应用层实现了类似 TCP 的可靠性、流量控制和拥塞控制,同时解决了 TCP 的队头阻塞问题。

五、UDP 应用层可靠性实现

虽然 UDP 本身不可靠,但应用程序可以在其之上构建自己的可靠性机制,形成一个“伪 TCP”:

  1. 确认机制 (ACK):应用程序发送数据后,等待接收方发送 ACK 确认。
  2. 重传机制 (Retransmission):如果规定时间内未收到 ACK,则重发数据。
  3. 序列号 (Sequence Number):为每个数据包添加序列号,用于乱序重排和去重。
  4. 流量控制:通过应用程序自定义的窗口机制,控制发送速率。
  5. 拥塞控制:应用程序可以根据 RTT 和丢包率来调整发送速率。

例如,QUIC 协议就是这样做的,它将原本 TCP 传输层的功能“下放”到了应用层,通过 UDP 作为承载,获得了更大的灵活性和性能优势。

六、总结

UDP 提供了一个极简、高效、无连接的传输服务。它牺牲了可靠性,换取了极高的传输效率和灵活性。因此,在对实时性要求高、允许少量丢包、或需要自定义传输机制的应用中,UDP 是一个比 TCP 更优的选择。理解 UDP 的特性及其与 TCP 的根本区别,是正确选择网络传输协议、构建高性能网络应用的关键。