运输层协议详解(一):无连接运输与UDP
UDP(用户数据报协议)是互联网协议套件中最核心的传输层协议之一。它遵循"尽最大努力交付"的原则,以最精简的方式提供了进程到进程的通信服务。
一、UDP 概述与设计哲学
1. 核心定位
UDP是一种无连接 、不可靠 的传输层协议。它在IP协议提供的主机到主机通信服务之上,仅增加了复用/分用 和简单的差错检测两项最小功能。
2. 设计哲学:简单与高效
-
无连接:发送数据前无需进行握手,减少了建立连接的开销和延迟。
-
无状态:服务器无需为通信维护连接状态,使得它可以同时向多个客户端发送数据。
-
轻量级:协议头部开销极小(仅8字节),处理逻辑简单,传输效率高。
3. 为何需要UDP?
尽管TCP提供了可靠传输,但其复杂的控制机制(如确认、重传、拥塞控制)会引入延迟 和速率波动 。对于许多应用而言,速度比完整性更重要。
4. 典型应用场景
-
实时多媒体应用:音视频通话、流媒体、网络电话。这些应用能容忍少量数据丢失,但对延迟和抖动极其敏感。
-
DNS(域名系统):简单的查询/应答模型,使用UDP能实现极高的效率和并发。
-
SNMP(简单网络管理协议):网络设备状态查询。
-
TFTP(简单文件传输协议):在稳定局域网内的小文件传输。
-
广播/多播应用:由于TCP是点对点连接,广播和多播只能使用UDP。
二、UDP 报文段结构
UDP的报文段结构极其简单,由8字节的头部 和数据载荷构成。
text
0 7 8 15 16 23 24 31
+--------+--------+--------+--------+ ---
| 源端口号 | 目的端口号 | ^
+--------+--------+--------+--------+ |
| 长度 | 校验和 | 8字节头部
+--------+--------+--------+--------+ |
| | ^
| 数据载荷 | 数据字段
| | v
+-----------------------------------+ ---
各字段详解:
-
源端口号 :发送方应用进程的端口号。这是一个可选字段,如果无需回复,可置为0。
-
目的端口号:接收方应用进程的端口号。这是多路分解的关键依据。
-
长度:整个UDP报文段(头部+数据)的字节长度。该字段的最小值为8(即只有头部,没有数据)。
-
校验和 :用于检测UDP报文段在传输过程中是否出现了差错。在IPv4中是可选的,在IPv6中是强制的。
三、UDP 检验和
1. 作用与目的
UDP检验和用于差错检测 ,目的是发现报文段在从源端到目的端的传输过程中,可能发生的比特翻转错误 (如0变1,1变0)。它提供的是端到端的完整性验证。
2. 计算范围:伪头部 + 头部 + 数据
UDP检验和的计算方法比较特殊,它不仅覆盖UDP报文段本身,还覆盖了来自IP层的一些字段,这部分被称为伪头部。
伪头部结构:
text
0 7 8 15 16 23 24 31
+--------+--------+--------+--------+
| 源IP地址 |
+--------+--------+--------+--------+
| 目的IP地址 |
+--------+--------+--------+--------+
| 全零 | 协议号 | UDP长度 |
+--------+--------+--------+--------+
- 协议号:对于UDP,该值为17。
3. 计算步骤
-
填充伪头部:在UDP报文段前添加伪头部。
-
补零:如果数据部分不是16位的整数倍,则在末尾填充一个字节的0(该填充不作为数据发送)。
-
反码求和:将整个序列(伪头部 + UDP头部 + 数据 + 填充)视为一系列16位的整数,将它们全部相加。
-
取反码 :将求和结果的二进制位取反 (1变0,0变1),得到的结果即为检验和。
-
存放:将计算出的检验和存入UDP头部的"检验和"字段。
4. 接收方验证
接收方执行完全相同的计算过程(包括添加伪头部)。如果计算结果全部为1(在反码运算中,全1表示-0,即没有错误),则认为报文段没有出错;否则,就静默地丢弃该报文段,或者将此错误上报给应用层。
详解:UDP检验和的计算时机与流程
简单来说,这是一个 "发送方计算,接收方验证" 的过程。它的核心思想是:发送方为数据生成一个"指纹",接收方通过核对这个"指纹"来判断数据在传输过程中是否被篡改或出错。
核心原则:发送方计算,接收方验证
-
发送方(数据出口):在将UDP报文段发送到网络之前,计算检验和,并将结果填入报文头的"检验和"字段。
-
接收方(数据入口):从网络收到UDP报文段后,立即重新计算检验和,并将计算结果与报文头中发送方填写的检验和进行比对。
详细工作流程
为了更直观地展示这一过程,下图清晰地描绘了检验和在发送和接收两端的工作流程:

接收方验证的深层原理
为什么接收方计算后结果为"全1"就代表数据正确?
这涉及到反码运算的特性:
-
发送方计算时,是先将所有数据(伪头部+头部+数据)相加,然后对和取反码,得到检验和。
-
接收方验证时,是将所有数据(伪头部+头部+数据 + 发送方计算的检验和)再次相加。
逻辑推导:
-
设发送方所有原始数据的和为
A。 -
发送方计算出的检验和是
~A(即A的反码)。 -
接收方计算的是
A + (~A)。 -
在反码算术中,
A + (~A) = 0xFFFF(即16个二进制位全是1)。 -
所以,如果数据完好无损,接收方的计算结果就是 0xFFFF(全1)。任何比特位出错都会导致这个结果发生变化。
一个简单的比喻
想象一下你要寄送一个装有钱的信封:
-
发送方计算:你在信封里放了一张纸条,上面写着"内含100元"。在封口前,你根据里面的钱数计算了一个"检验码"(比如100的特定编码)写在信封外面。
-
接收方验证 :收信人收到信封后,先不拆开。他先看看你外面写的"检验码"是多少。然后他隔着信封清点里面的钱数,并根据同样的算法计算出一个"检验码"。
-
如果他算出来的码和你写在信封外面的码对得上,他就确信钱数没错,可以拆开使用了。
-
如果对不上,他就知道钱可能在路上被偷换或少了一张,他会直接拒收这个信封(丢弃报文)。
-
总结一下:
-
时机 :发送在发送前 计算;接收方在接收后、交付应用前验证。
-
目的:提供一种端到端的轻量级差错检测机制。
-
结果:验证通过,数据上交;验证失败,数据丢弃。UDP本身不会要求重传,这个决定权交给了上层的应用程序。
5. 为何包含伪头部?
包含伪头部是为了验证UDP报文段是否被错误地交付。它能检测出IP地址错误或IP协议字段错误的情况,确保这个UDP报文段确实是发送给本主机上正确的传输层协议的。
UDP 的局限性总结
-
不可靠:不保证数据报能到达终点;不保证数据报按序到达;不保证数据报只到达一次。
-
无拥塞控制:无论网络状况如何,都以恒定速率发送数据。这既是优点(适合实时应用),也是缺点(可能加剧网络拥塞,影响其他流量)。
总结
UDP以其简单、高效、低延迟 的特性,在互联网中扮演着不可替代的角色。它放弃了TCP的复杂性和可靠性,换取了极致的速度,完美契合了那些"时效性重于完整性 "的应用需求。理解UDP,就是理解了在网络通信中,没有一种协议是万能的,所有的设计都是在性能、可靠性和复杂度之间做出的权衡。