CHARLIE SAYS

查理如是说
DATE 2026-08-24
THEME
SERIES / NETWORK / P-155 · 网络协议

网络协议 006:UDP 协议详解

UDP 概述

UDP(User Datagram Protocol) 即用户数据报协议,在网络中它与 TCP 协议一样用于处理数据包,是一种无连接的协议。在 OSI 模型中,在第四层——传输层,处于 IP 协议的上一层。UDP 用来支持那些需要在计算机之间传输数据的网络应用,包括网络视频会议系统在内的众多的客户/服务器模式的网络应用都需要使用 UDP 协议。

UDP 协议从问世至今已经被使用了很多年,虽然其最初的光彩已经被一些类似协议所掩盖,但是即使是在今天 UDP 仍然不失为一项非常实用和可行的网络传输层协议。UDP 报文没有可靠性保证、顺序保证和流量控制字段等,可靠性较差。但是正因为 UDP 协议的控制选项较少,在数据传输过程中延迟小、数据传输效率高,适合对可靠性要求不高的应用程序,或者可以保障可靠性的应用程序,如 DNS、TFTP、SNMP 等。

UDP 特点

UDP 提供不可靠服务,具有 TCP 所没有的优势:

  • UDP 无连接,时间上不存在建立连接需要的时延。空间上,TCP 需要在端系统中维护连接状态,需要一定的开销,此连接装入包括接收和发送缓存、拥塞控制参数和序号与确认号的参数;UDP 不维护连接状态,也不跟踪这些参数,开销小,空间和时间上都具有优势。举个例子:
    • DNS 如果运行在 TCP 之上而不是 UDP,那么 DNS 的速度将会慢很多;
    • HTTP 使用 TCP 而不是 UDP,是因为对于基于文本数据的 Web 网页来说,可靠性很重要;
    • 同一种专用应用服务器在支持 UDP 时,一定能支持更多的活动客户机。
  • 分组首部开销小,TCP 首部 20 字节,UDP 首部 8 字节。
  • UDP 没有拥塞控制,应用层能够更好地控制要发送的数据和发送时间,网络中的拥塞控制也不会影响主机的发送速率。某些实时应用要求以稳定的速度发送,能容忍一些数据的丢失,但是不能允许有较大的时延(比如实时视频、直播等)。
  • UDP 提供尽最大努力的交付,不保证可靠交付。所有维护传输可靠性的工作需要用户在应用层来完成,没有 TCP 的确认机制、重传机制,如果因为网络原因没有传送到对端,UDP 也不会给应用层返回错误信息。
  • UDP 是面向报文的,对应用层交下来的报文,添加首部后直接向下交付给 IP 层,既不合并,也不拆分,保留这些报文的边界。对 IP 层交上来 UDP 用户数据报,在去除首部后就原封不动地交付给上层应用进程,报文不可分割,是 UDP 数据报处理的最小单位。正是因为这样,UDP 显得不够灵活,不能控制读写数据的次数和数量。比如我们要发送 100 个字节的报文,我们调用一次 sendto 函数就会发送 100 字节,对端也需要用 recvfrom 函数一次性接收 100 字节,不能使用循环每次获取 10 个字节、获取十次这样的做法。
  • UDP 常用于一次性传输比较少量数据的网络应用,如 DNS、SNMP 等,因为对于这些应用,若是采用 TCP,为连接的创建、维护和拆除带来不小的开销。UDP 也常用于多媒体应用(如 IP 电话、实时视频会议、流媒体等),数据的可靠传输对他们而言并不重要,TCP 的拥塞控制会使他们有较大的延迟,也是不可容忍的。
  • UDP 支持一对一、一对多、多对一和多对多的交互通信

还要注意的是:

  • IP 数据报要经过互连网中许多路由器的存储转发;UDP 用户数据报是在运输层的端到端抽象的逻辑信道中传送的;
  • UDP 对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。应用层交给 UDP 多长的报文,UDP 就照样发送,即一次发送一个报文。

UDP 的首部格式

UDP 首部共 4 个字段、8 个字节。在计算检验和时,临时把”伪首部”和 UDP 用户数据报连接在一起,伪首部仅仅是为了计算检验和。

字段说明
源端口占 16 位、源端口号,在需要对方回信时选用,不需要时可用全 0
目的端口占 16 位、目的端口号,这在终点交付报文时必须使用
长度占 16 位、UDP 用户数据报的长度,其最小值是 8(仅有首部)
检验和占 16 位、检测 UDP 用户数据报在传输中是否有错,有错就丢弃

请注意,虽然在 UDP 之间的通信要用到其端口号,但由于 UDP 的通信是无连接的,因此不需要使用套接字。

UDP 校验

UDP 校验和的计算方法和 IP 数据报首部校验和的计算方法相似,都使用二进制反码运算求和再取反,但不同的是:IP 数据报的校验和只检验 IP 数据报的首部,但 UDP 的校验和是把首部和数据部分一起校验。

发送方,首先是把全零放入校验和字段并且添加伪首部,然后把 UDP 数据报看成是由许多 16 位的子串连接起来,若 UDP 数据报的数据部分不是偶数个字节,则要在数据部分末尾增加一个全零字节(此字节不发送),接下来就按照二进制反码计算出这些 16 位字的和,将此和的二进制反码写入校验和字段。

在接收方,把收到的 UDP 数据报加上伪首部(如果不为偶数个字节,还需要补上全零字节)后,按二进制反码计算出这些 16 位字的和。当无差错时其结果全为 1,否则就表明有差错出现,接收方应该丢弃这个 UDP 数据报。

注意:

  • 校验时,若 UDP 数据报部分的长度不是偶数个字节,则需要填入一个全 0 字节,但是此字节和伪首部一样,是不发送的;
  • 如果 UDP 校验和校验出 UDP 数据报是错误的,可以丢弃,也可以交付上层,但是要附上错误报告,告诉上层这是错误的数据报;
  • 通过伪首部,不仅可以检查源端口号、目的端口号和 UDP 用户数据报的数据部分,还可以检查 IP 数据报的源 IP 地址和目的地址。这种差错检验的检错能力不强,但是简单,速度快。

参考文章

系列导航

← JHipster 开发 06:实体代码生成深潜——JDL 从入门到驯服 目录 开发工具 006:Lombok工具库详解 →
← 返回文章列表