简介
UDP(User Datagram Protocol,用户数据报协议),一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,UDP在IP报文的协议号是17。常用的UDP端口号有:53(DNS)、69(TFTP)、161(SNMP),使用UDP协议包括:TFTP、SNMP、NFS、DNS、BOOTP、CoAP、DTLS。
特点
- UDP是无连接的,减少开销和发送数据之前的时延
- UDP使用最大努力交付,即不保证可靠交付
- UDP是面向报文的,适合一次性传输少量数据的网络应用
- UDP无拥塞控制,适合很多实时应用
- 首部开销小,仅8个字节(TCP首部为20个字节)
报文格式
报文位置
报文格式
- 源端口号:在需要对方回信时选用,不需要时可用全0。
- 目的端口号:这在终点交付报文时必须使用。
- 长度:UDP用户数据报的总长度(首部+数据),其最小值是8(仅有首部)。
- 检验和:检测UDP用户数据报在传输中是否有错,有错就丢弃。
如果接收方发现收到的报文中的目的端口号不正确(即不存在对应于该端口号的应用进程),就丢弃该报文,并由网际控制报文协议ICMP发送“端口不可达”差错报文给发送方。我们在ICMP的应用举例讨论 traceroute时,就是让发送的UDP用户数据报故意使用一个非法的UDP端口,结果ICMP就返回“端口不可达”差错报文因而达到了测试的目的。
UDP校验
伪首部
UDP伪首部
- 源IP地址:4个字节
- 目的IP地址:4个字节
- 0:1个字节,即0x00
- 17:1个字节,即0x11,封装UDP报文的IP数据包首部协议字段是17
- UDP长度:2个字节,UDP首部(8B)+数据部分长度,不包括伪首部伪首部仅在计算校验和的时候才出现,不向下传送也不向上递交。
发送端校验
- 填上伪首部
- 全0填充检验和字段
- 全0填充数据部分(UDP数据报要看成许多4B的字串接起来)
- 伪首部+首部+数据部分采用二进制反码求和
- 把和求反码,填入校验和字段
- 去掉伪首部,发送
发送端计算校验和
进位及回加
按列计算:9(1001),余1,进100;7+0=1(111),余1进11;7+1=8(1000),余0进100;...后续读者动手计算吧,记得多出去的进位回加到低位,如果不习惯一起算,可以两个加一次。16位的话按列计算16次左右,如果有二三十个相加的话,按列相加比较快速,使用16进制相加也会更快一点。
接收端校验
1.填上伪首部
2.伪首部+首部+数据部分采用二进制反码求和(校验和部分不是全0了,而是0110100100010010)
3.结果全为1,则无差错,否则丢弃数据报/交给应用层附上出差错的警告。
计算过程和上面一样,只是校验和变了。
这样的检验和, 既检查了UDP用户数据报的源端口号和目的端口号以及UDP用户数据报的数据部分,又检查了IP数据报的源IP地址和目的地址。
实战
UDP泛洪攻击(UDP Flood Attack),攻击者发送伪造源地址和端口不可达的UDP数据报,当受害系统接收到一个 UDP 数据报的时候,它会确定目的端口正在等待中的应用程序。当它发现该端口中并不存在正在等待的应用程序,它就会产生一个目的地址无法连接的ICMP数据包发送给该伪造的源地址。如果发送的足够多的,就会消耗受害系统的资源,造成攻击。和TCP是SYN攻击差不多,也是(D)DoS攻击的一种。
自己实现UDP客户端和服务器端可以查看文章:python-网络编程之socket
参考
《TCP/IP详解I》
《计算机网络(谢希仁)第七版》