UDP-Lite 允许「只校验一部分数据」:剩下的错了也照样交给应用。 它不是「更好的 UDP」,只适合「明确知道自己能容错」的业务。
6.3 讲了 UDP 的校验和覆盖整个包,这一节讲「不覆盖全部」的变体。 6.6 会逐字节讲 UDP 首部,UDP-Lite 只改了一个字段的含义。
一、它改了什么
UDP 的校验和覆盖「首部加全部数据」,一旦有一位错,整个包被丢掉。 UDP-Lite 把「长度」字段改成了「校验覆盖长度」,于是可以只校验前一部分。 这个改动小得可怜,只有一处: 但它的后果很大——「错了也照样送上去」意味着应用必须自己判断「这段数据还能不能用」。 所以它和 UDP 的关系,不是「升级」而是「换了一种取舍」: UDP 宁可丢掉也不送坏数据,UDP-Lite 宁可送坏数据也不丢。
二、为什么需要它
因为语音和视频编码本身有容错能力——丢一帧、错几个字节,解码器能糊过去,听感上只是轻微杂音。 而「整包丢掉」反而更糟:解码器要重新同步,听到的是明显的断裂。 所以「让它错着过去」比「干脆丢掉」更好。 注意这个理由的适用范围很窄:只有「能容错的编码」才成立, 换成文件传输、数据库协议,这个逻辑立刻反了——坏数据比没数据更糟。
三、代价
第一是不校验的部分「错了没人知道」: 如果应用没有容错能力,就是把「损坏数据」当「正确数据」用。 这种错误很难查,因为它不会报错,只会「结果不对」。 第二是「中间设备不一定认」:它用的是 UDP 之外的另一个协议号(136), 所以防火墙、NAT 很可能直接把它当未知协议丢掉。 这也是它几乎没人用的现实原因——和 SCTP、DCCP 一样,卡在「部署」上,不是卡在「设计」上。
四、动手 Demo:UDP-Lite 只校验「该校验的部分」
算三种覆盖长度下,有多少字节是「不校验」的。 覆盖率越低,容错能力换来的风险越大。
total = 1000
for cov in (200, 500, 1000):
print('覆盖 %4d 字节,不校验 %4d 字节,覆盖率 %.0f%%'
% (cov, total - cov, 100.0 * cov / total))
实跑输出:
--------------------------------------------------------------------
UDP-Lite 只校验「该校验的部分」
--------------------------------------------------------------------
**UDP 的校验和覆盖整个包**:**一旦有一位错,整个包被丢掉。**
**UDP-Lite 允许「只校验前一部分」,剩下的错了也照样交给应用。**
校验覆盖(字节) 不校验(字节) 覆盖率
-----------------------------------------------
200 800 20%
500 500 50%
1000 0 100%
**为什么会有这种需求**:**语音和视频编码本身有「容错」能力**——
**丢一帧、错几个字节,解码器能糊过去,听感上只是轻微杂音。**
**而「整包丢掉」反而更糟**:**解码器要重新同步,听到的是明显的断裂。**
**所以「让它错着过去」比「干脆丢掉」更好。**
**代价也很明确**:**不校验的那部分,错了没人知道**,
**如果应用没有容错能力,就是把「损坏数据」当「正确数据」用。**
**所以 UDP-Lite 只能用在「明确知道自己能容错」的场景**,**不能当成「UDP 的升级版」到处开。**
「覆盖 1000」就是普通 UDP 的行为:全包校验,错一个字节就丢。 所以 UDP-Lite 是「UDP 的超集」——把覆盖长度设成总长度,行为就完全一样了。 中间那种「覆盖 200」是最典型的用法:头部和「关键参数」必须对,载荷可以错。 比如语音编码里「帧类型、时间戳」不能错,但「采样值」错几个,听感上只是杂音。 最后一个提醒:这个协议号是 136,所以「抓包看不到它」很可能是「路上被丢了」, 不是「本机没发出去」。 排查时先确认路径上的设备认不认这个协议号。
30 秒实验
- 想一下:为什么「坏数据」有时比「没数据」更好?
- 算一下:覆盖 800 字节、总长 1000,不校验多少字节?
- 想一下:UDP-Lite 为什么没普及?
常见误区
- 以为「UDP-Lite 是 UDP 的升级版」。 是另一种取舍,只适合能容错的业务。
- 以为「不校验更省 CPU」。 省得很少,主要目的是「别丢掉可用的数据」。
- 以为「它能穿过所有防火墙」。 协议号 136,很多设备直接不认。
自测三问(点开对答案)
1. UDP-Lite 改了 UDP 的哪个字段? —— **「长度」字段变成「校验覆盖长度」**,据此只校验前一部分。 2. 它适合什么业务? —— **语音、视频这类「编码本身能容错」的业务**,坏了也比丢了强。 3. 它的协议号是多少? —— **136**,和 UDP 的 17 不同,所以很多设备不认。下一节看一个「想同时要可靠和不阻塞」的协议:SCTP。
- ☐ (本节完,下一节 6.5.2 SCTP)