Skip to content

UDP 协议

2026 大纲 五(二)1 UDP 数据报五(二)2 UDP 校验。传输层为什么存在、端口为什么取代进程标识符、无连接与面向连接的本质差别写在 TCP 与 UDP 对比

一、只加两件事,为什么还值得设一个协议

IP 把分组交到目的主机的网络层就算完成任务,而真正在通信的是主机里的应用进程;IP 首部里也有检验和,但它只检验首部、不检验数据部分

UDP 补的正是这两处缺口,也只补这两处:在 IP 数据报服务之上只增加复用分用差错检测,其余可靠性机制全部拿掉。

一份数据要到达进程,得过两道分用关:先按 IP 首部的协议字段挑协议(UDP = 17,TCP = 6),再按目的端口挑进程。

复用分用是刚需(少了它 IP 数据没法交付进程),可靠性机制则是可选的。把可选的全部拿掉,剩下这个 8 字节的最小传输层——它的设计意图是给应用留一条"我自己来"的通道,而不是"TCP 的残缺版"。

交互可视化

加载可视化中...

二、五个特点全部由"首部只有 8 字节"推出

特点它买到了什么它的代价
无连接省掉一次握手的 RTT 与两端的连接状态表收方无法预分配缓存,也不知道"对方还在不在"
不可靠不用维护重传队列与计时器丢了就是丢了,失序不纠正
面向报文边界天然保留,一次发对应一次收"报文该多大"被推给应用
无拥塞控制发送速率恒定,实时性有保障拥塞时不让路,挤压自觉降速的 TCP
支持一对多、多对多能做广播与多播—(TCP 做不到,连接天生只有两个端点)
首部只有 8 字节小报文开销远低于 TCP 的 20 字节放不下序号、确认号、窗口

最后一行是因,前面几行是果。 首部里没有地方放序号,就无法确认、无法重传、无法排序、无法做窗口——"不可靠""无拥塞控制"是首部尺寸的必然推论。

被推给应用的那个决定两头都很硬:太长则 IP 层要分片,而任何一片丢失整个 IP 数据报都要丢弃(IP 不做分片重传),丢包率被放大;太短则一份数据要背 20 + 8 字节首部,线路上传的绝大部分是首部。

顺带澄清一处:面向报文不等于一定不分片。 UDP 自己既不合并也不拆分,但交给 IP 之后 IP 层照样可能分片;UDP 保留的是应用层看到的边界——IP 层会先重组再上交,应用拿到的仍是完整的一份。

还有一条行为要记:目的端口不存在时,UDP 丢弃报文并由 ICMP 回"端口不可达"(TCP 是自己回 RST,因为 UDP 首部里没有任何标志位能表达"拒绝")。traceroute 判断"已到终点"靠的正是这条。

三、UDP 首部格式

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          源端口号             |          目的端口号           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            长度               |           校验和              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

四个字段各 2 字节,合计 8 字节源端口在需要对方回信时选用,不需要时可填全 0

长度字段 = 首部 + 数据,最小值 8(仅有首部)。所以数据长度恒为 L8——题面给"长度 1000",数据部分只有 992

两处数字很容易记混,一起厘清:

1472 与 1480 不是一回事。 以太网上不触发 IP 分片时,UDP 数据的上限是 1500208=1472 字节,而此时长度字段填的是 1472+8=1480

数据最大是 65527 还是 65507,取决于问的是哪个口径:只按 UDP 长度字段算是 655358=65527;放进 IPv4 数据报里实际能装的是 65535208=65507

拿 IP 总长度减去 IP 首部长度就能算出 UDP 数据报多长,长度字段看似冗余,但两个理由让它必须存在:① UDP 不应该去读 IP 首部,分层要求每层只依赖本层看得到的信息;② 校验和需要它——伪首部里要填 UDP 长度,若它只存在于 IP 首部,被改掉时就察觉不了。

四、校验和:伪首部到底在防什么

只校验 UDP 首部与数据,查出的是"内容在路上被改了"。把伪首部拼进来,多查出三类错:

多查出的错靠什么拦住
送错主机:目的 IP 被改坏,分组送到了 CC 用伪首部里自己的 IP 去算就对不上,丢弃。没有伪首部时 C 会以为这份数据本来就是给自己的
送错协议:协议字段被改成 17,TCP 报文段误交给 UDP协议号参与计算
长度被改长度在 UDP 首部与伪首部里各出现一次,改一处必然不匹配

伪首部把校验从"内容对不对"升级成"是不是本来就该交给我"。

伪首部共 12 字节:源 IP 4 + 目的 IP 4 + 全零 1 + 协议号 1(UDP 填 17,TCP 填 6)+ UDP 长度 2。它既不向下传送也不向上递交,只在算校验和时临时拼在前面。

算法四步:字段置零 → 按 16 位分组(数据是奇数字节时末尾补一个全零字节)→ 带循环进位的反码求和(溢出的高位加回低位)→ 取反填入。

补的那个全零字节不发送,也不计入长度字段——所以奇数长度的数据报,长度字段永远是奇数。

接收端凭什么判无错:它把收到的校验和一并算进去,结果全 1(0xFFFF) 即无差错。道理在反码算术里——一个数加上自己的反码恒为全 1,所以接收端根本不必知道发送端原来算出的和是多少。

两条边界要记住。UDP 校验和是可选的,TCP 是强制的:UDP 不算时字段填 0;但若算出来的结果恰好是 0,要填全 1(0xFFFF),否则会被对方误当成"没算"。检错能力有边界:它能查出任何单比特翻转,但查不出两处互相抵消的差错(一个字加 1、另一个字减 1)。更强的检错要靠链路层的 CRC

完整算一次 UDP 校验和(第一次学、或想手动跑一遍带循环进位的反码求和时展开)

主机 192.168.1.10 的 1025 端口向 192.168.1.20 的 53 端口发一个 UDP 数据报,数据部分是 5 个字节 N E T 4 0(ASCII 依次为 0x4E、0x45、0x54、0x34、0x30)。

第 1 步:先定长度。 数据 5 字节 + 首部 8 字节,长度字段 = 13(0x000D)。长度在 UDP 首部与伪首部里各出现一次,先算出来后面两处直接填,避免填成"数据长度 5"。

第 2 步:拼出参加计算的字节串。

内容(十六进制,按 16 位字分组)
伪首部 12 字节C0A8 010A(源 IP 192.168.1.10) C0A8 0114(目的 IP 192.168.1.20) 0011(全零字节 0x00 + 协议号 17=0x11) 000D(UDP 长度 13)
UDP 首部 8 字节0401(源端口 1025) 0035(目的端口 53) 000D(长度 13) 0000(校验和先置零)
数据 5 字节 + 填充4E45 5434 3000(末字节 0x30 后补一个全零字节)

一共 26 字节 = 13 个 16 位字。补的那个 0x00 只用于凑够 16 位分组,不发送、也不算进长度字段——所以长度仍是 13 而不是 14。

第 3 步:逐字做带循环进位的加法。

#加数累计和
1C0A8C0A8
2010AC1B2
3C0A81825A → 进位回卷 → 825B
40114836F
500118380
6000D838D
70401878E
8003587C3
9000D87D0
10000087D0
114E45D615
12543412A49 → 进位回卷 → 2A4A
1330005A4A

进位要"加回低位"而不是丢掉,这是反码算术与普通补码加法的唯一区别:溢出的那个 1 代表 216,在模 2161 的意义下等于 1。丢掉它,接收方就永远算不出全 1。

第 4 步:取反码填入。 求和结果 S=5A4A,故

检验和=S=A5B5=1010010110110101

接收端复算。 把校验和字段照收到的值原样保留,连同伪首部再做一次反码求和:S+S=5A4A+A5B5=FFFF,全 1,判无差错。

再验它确实能查错:把数据首字节由 0x4E 改成 0x4F(只翻一位),第 11 个字变成 4F45,总和 +1 变成 5A4B,接收端算出 5A4B + A5B5 回卷后得 0100,不是全 1,检出差错

教材对这套方法的评价是"检错能力并不强,但它的好处是简单,处理起来较快"。TCP 校验和用完全相同的算法与同样 12 字节伪首部,只把协议号 17 改成 6、UDP 长度改成 TCP 报文段长度

五、何时选 UDP,可靠性该放哪一层

应用端口选择 UDP 的原因
DNS53一问一答、报文短,建连接开销比查询本身还大
DHCP67/68客户端尚无 IP,必须靠广播,TCP 不支持
TFTP69场景简单,可靠性交给应用层自己做
实时音视频 RTP重传回来的帧已经过期
SNMP / RIP161 / 520报文简短、周期性重发,丢一次下一周期自然更新

归纳成三条判据就能应对没见过的应用:重传是否还有意义 / 建连接开销是否超过数据本身 / 是否需要广播多播。任一成立即倾向 UDP。

UDP 本身不可靠,基于它的应用却可以很可靠:TFTP 在应用层做停止-等待,DNS 超时就重发查询,QUIC 在 UDP 之上重建了连接管理、可靠传输、拥塞控制与多路复用。"可靠"不是某一层的属性,而是某一层选择实现的机制。

那为什么不把可靠性全塞进传输层(想弄清何时该用 TCP、何时该自己在 UDP 上做时展开)

可靠性的实现方式与应用需求强相关:TFTP 需要的是"每块都确认",实时视频需要的是"丢了就算了但要有序",QUIC 需要的是"不同流互不阻塞"。TCP 只能提供一套固定的可靠性,谁也满足不了全部。UDP 把这个决定权交还给应用——这就是它存在的价值。

反过来也有边界:这不意味着"应用层做可靠性总是更好"。应用层做要自己维护序号、计时器、重传队列,重写一遍 TCP 已经解决过的问题;而且应用层看不到 RTT 的准确测量与网络拥塞信号,做出的重传策略往往比 TCP 更糟。所以判据是:需求与 TCP 提供的那套一致时用 TCP,明显不一致时才自己在 UDP 上做。

本节小结

  1. UDP 在 IP 之上只加了复用分用与差错检测两件事。 端口把数据从"主机"送到"进程",校验和补上 IP 首部检验和不覆盖数据部分的缺口;一份数据到进程要过两道分用关:先按协议字段(UDP = 17)挑协议,再按目的端口挑进程。
  2. 五个特点全部由"首部只有 8 字节"推出:放不下序号 → 无法确认与重传 → 不可靠、无拥塞控制。面向报文既不合并也不拆分,于是"报文该多大"被推给应用:太长会触发 IP 分片而丢一片废一报,太短则首部开销占比过高。
  3. 校验和覆盖伪首部 + 首部 + 数据,伪首部 12 字节不发送也不上交,作用是把校验升级成"是不是本来就该交给我"。算法是置零 → 16 位分组 → 带循环进位的反码求和 → 取反;接收端把收到的校验和一并算入,结果全 1 即无差错。

考点速记

UDP 在真题里被考过的形式有三种,三种问的都是"8 字节首部"这件事的三个不同后果:怎么算、开销多大、省下多少时间

① 校验和的最后一步是什么(cn-2024-39)。给出中间结果 1011 1001 1011 0110,再加最后一个 16 位数 0110 0101 1100 0101,问最终的校验和。

两步都不能省:

0xB9B6+0x65C5=0x11F7B回卷0x1F7B+1=0x1F7C校验和=∼0x1F7C=0xE083=1110000010000011

C四个选项精确对应四种做法:A 是既没回卷也没取反,B 是回卷了但忘了取反,D 是回卷时把进位加错了位再取反。B 这个干扰项最要命——算到 0x1F7C 就以为做完了,是这道题最容易停错的地方。填入首部的永远是"和的反码",不是和本身。

② 12 字节数据的传输效率(cn-2021-39)。同样 12 B 的应用层数据,分别用 1 个 UDP 数据报和 1 个 TCP 段传输,问最大传输效率。

UDP=1212+8=60%,TCP=1212+20=37.5%

D两处要点:一是"最大"这个词——TCP 首部可以到 60 字节,只有取最小的 20 字节(不带任何选项)才是最大效率;二是分母只算传输层首部,题目问的是"该 UDP 数据报和 TCP 段"的效率,不含 IP 首部。选项里的 37.5% 出现了两次,就是给"把 UDP 也按 20 字节算"的人准备的。

③ 同一个服务,走 UDP 和走 TCP 各要多久(cn-2025-39)。客户向 Time 服务器请求时间,RTT = 8 ms,问分别走 UDP 与 TCP 所需的最少时间。

UDP:8 ms。 无连接,请求发出去、响应回来,正好 1 个 RTT。

TCP:16 ms。 必须先建连接。三次握手中,客户发 SYN、收 SYN+ACK 用掉 1 个 RTT;此后客户发出的第三次握手 ACK 可以携带数据(即请求本身),服务器收到后回响应,再用 1 个 RTT。合计 2 RTT = 16 ms

B这道题是"建连接的开销是否超过数据本身"这条判据的量化版——请求一次时间只要几个字节,为它多付一个 RTT 显然不划算,所以 Time 这类服务天然该走 UDP。

本篇练习区里还会出现两道题:cn-2014-39 问 UDP 的三条叙述哪几条正确,讲在 TCP 与 UDP 对比;cn-2025-39 的另一半(TCP 那一侧的 2 RTT)依赖三次握手的时序,讲在 TCP 连接管理

易错校验和的最后一步是取反。 算到求和结果就停下,正好落进干扰项。

易错反码求和的进位要加回低位,不能丢。 丢了接收端就永远算不出全 1。

易错算传输效率时 TCP 要取最小首部 20 字节(问"最大效率"),UDP 是固定 8 字节。

易错走 TCP 要多付一个 RTT 建连接,但第三次握手的 ACK 可以携带数据,所以是 2 RTT 不是 2.5 RTT。

易错长度字段 = 首部 + 数据,数据长度是 L8。以太网上数据上限 1472,但长度字段填 1480。

易错奇数字节时补的那个全零字节不发送、不计入长度字段。

易错UDP 校验和可选、TCP 强制;不算时填 0,算出来恰好是 0 则填全 1。

易错面向报文不等于不分片。 UDP 自己不拆,但 IP 层照样可能分片。

易错目的端口不存在时 UDP 借 ICMP 回"端口不可达",TCP 是自己回 RST。

教材出处
  • 谢希仁《计算机网络》(第 8 版)p215(5.2.1 UDP 概述):"用户数据报协议 UDP 只在 IP 的数据报服务之上增加了很少一点的功能,这就是复用和分用的功能以及差错检测的功能。" 本篇第一节的整个框架就是这句话的展开。
  • 同书 p216:面向报文的完整表述——"UDP 对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界……因此,应用程序必须选择合适大小的报文。若报文太长,UDP 把它交给 IP 层后,IP 层在传送时可能要进行分片,这会降低 IP 层的效率。反之,若报文太短……会使 IP 数据报的首部的相对长度太大"。第二节"报文太长 / 太短"两头的代价即出自此处。
  • 同书 p212 脚注:"IP 层也有复用和分用的功能,即在发送方使用不同协议的数据都可以封装成 IP 数据报发送出去,而在接收方的 IP 层根据 IP 首部中的协议字段进行分用"——本篇"两道分用关"的依据。
  • 同书 p212"运输层还要对收到的报文进行差错检测……在网络层,IP 数据报首部中的检验和字段,只检验首部是否出现差错而不检查数据部分。" 这是"为什么 UDP 还要自己算一次校验和"的直接答案。
  • 同书 p217(5.2.2 UDP 的首部格式):四个字段的定义,"长度 UDP 用户数据报的长度,其最小值是 8(仅有首部)"、"源端口 源端口号。在需要对方回信时选用。不需要时可用全 0"。
  • 同书 p218:伪首部与校验和算法的完整描述——"所谓'伪首部'是因为这种伪首部并不是 UDP 用户数据报真正的首部……伪首部既不向下传送也不向上递交,而仅仅是为了计算检验和";"若 UDP 用户数据报的数据部分不是偶数个字节,则要填入一个全零字节(但此字节不发送)";"在接收方……按二进制反码求这些 16 位字的和。当无差错时其结果应为全 1";以及对检错能力的评价"这种简单的差错检验方法的检错能力并不强,但它的好处是简单,处理起来较快"。同页还给出"目的端口号不正确就丢弃该报文,并由 ICMP 发送'端口不可达'差错报文"。本篇折叠块里的算法与自检口径全部依此页。
  • 同书 p228(5.5 TCP 报文段的首部格式,第 13 条"检验和"):TCP 校验和"要在 TCP 报文段的前面加上 12 字节的伪首部。伪首部的格式与图 5-5 中 UDP 用户数据报的伪首部一样。但应把伪首部第 4 个字段中的 17 改为 6(TCP 的协议号是 6),把第 5 字段中的 UDP 长度改为 TCP 长度"。

相关知识

TCP 与 UDP 对比TCP 协议基础IP 数据报格式IP 分片ICMP

真题练习