目录
1. 引言
UDP是面向数据报的运输层协议,数据报封装成一份IP数据报的格式
注意:
- 不提供可靠性
- IP数据报长度超过网络的MTU的话要对IP数据报进行分片(源端到目的端之间的每个网络都要)
2. UDP首部
注意:
- TCP和UDP端口号相互独立,但若两者同时提供某种服务,两个协议一般选择相同的端口号
- UDP长度字段指的是UDP首部+UDP数据的字节长度,UDP数据报长度=IP数据报全长-IP首部的长度
3. UDP检验和
- UDP检验和覆盖其首部和数据,不像IP首部的检验和只覆盖IP的首部。
- UDP伪首部是为了计算检验和而设的,目的是让UDP两次检查数据是否已正确到达目的地。
- 检验和计算结果为0,则存入值全1;若传送的检验和为0,说明发送端未计算检验和。
- 发送端未计算检验和而接收端检测到检验和有错的话,UDP数据报就会被悄悄丢弃,不会产生任何差错报文。
- 是端到端的检验和,发送端计算,接收端验证。
3.1 tcpdump输出
打印出的值为0则说明发送端没有计算检验和
送出的数据报与收到的数据报具有相同的检验和值
3.2 一些统计结果
TCP发生检验和差错的比例比UDP要高得多,可能是因为该系统中TCP连接常为 “远程” 连接,而UDP一般为本地通信,所以说不能完全相信数据链路(如以太网、令牌环等)的CRC检验,端到端的检验和功能也应该打开。
4. IP分片
IP将MTU与数据报长度进行比较,如果需要则进行分片(可以在原始发送端主机上,也可以在中间路由器上),到达目的地(下一跳)时进行重新组装,组装由目的端的IP层完成。
IP首部中与IP分片相关的字段:
16bit标识、标志、13bit片偏移。标识字段包含一个唯一值,在分片时被复制到每个片中;标志字段用其中一位来表示 “更多的片”,除最后一片外其他每个片都将该位置1,还有一位 “不分片” 位,若该位置1表示IP不会对数据报进行分片;片偏移指的是该片偏移原始数据报开始处的位置。
注意:
- 只丢失一片数据也要重传整个数据报,因为IP层本身没有超时重传机制
- 使用UDP很容易导致IP分片(以太网上数据帧的最大长度为1500字节,其中IP首部20字节,UDP首部8字节,剩下的1472字节留给数据)
- 任何运输层的首部只出现在第1片数据中
- IP数据报是指IP层端到端的传输单元,分组是指在IP层和链路层之间传送的数据单元
5. ICMP不可达差错(需要分片)
当路由器收到一份需要分片的数据报,而在IP首部又设置了不分片(DF)的标志比特时也会发生ICMP不可达差错。
若路由器未提供这种新的ICMP差错报文格式,那么下一站的MTU就设为0
举例:
增加数据分组长度直到看见进入的分组被分片,从而判断它的MTU
6. 用Traceroute确定路径MTU
发送分组,并设置 “不分片” 标志比特,发送的第一个分组的长度正好与出口MTU相等,每次收到ICMP “不能分片” 差错时就减小分组长度。
若路由器发送的ICMP差错报文是新格式,包含了出口的MTU,那么就用该MTU值来发送,否则就用下一个最小的MTU值来发送。
7. 采用UDP的路径MTU发现
如果允许路径MTU发现,那么当UDP应用程序写入可能被分片的数据报时,该数据报就会被丢弃。
8. UDP和ARP之间的交互作用
注意:
- 第一个到达数据报片出现时,IP层必须启动一个定时器(30s或60s),若超时而该数据报的所有片未能全部到达则将这些片丢弃。
- 多数BSD派生的系统会设置定时器,在定时器溢出时丢弃数据报片,但不生成ICMP差错
- 除非收到第一个数据报片,否则并不要求任何实现产生ICMP差错,因为没有运输层首部的话,ICMP差错接收者区分不了是哪个进程所发送的数据报被丢弃
9. 最大UDP数据报长度
IP数据报最大长度为65535字节,IP首部20字节,UDP首部8字节,理论上UDP数据报中用户数据最大长度为65507字节,但实际上UDP应用程序数据被限制成512字节或更小。
9.1 长度限制因素
- 应用程序受其程序接口的限制
- TCP/IP内核实现特性或差错
9.2 数据报截断
当接收到的数据报长度大于应用程序能够处理的长度:
- Berkeley版socket API对数据报进行截断
- SVR4下的socket API不截断数据报,超出的数据在之后的读取中返回
- TLI API返回一个标志表明可获得更多数据,应用程序后面的读操作返回数据报的其余部分
注意:
TCP为应用程序提供的是连续的字节流,不会发生数据丢失
10. ICMP源站抑制差错
接收数据报的速度比处理速度快时,可能会产生该差错。
- 源站抑制会消耗网络带宽,且对于拥塞来说是一种无效而不公平的调整
- 若采用UDP协议,那么BSD实现通常会忽略其接收到的源站抑制报文
11. UDP服务器的设计
11.1 客户IP地址及端口号
IP首部包含了源端和目的端IP地址,UDP首部包含了源端和目的端的UDP端口号,应用程序接收到UDP数据报时OS会告诉它是谁发送了该消息,即源IP地址和端口号,这样UDP服务器就可以对多个客户进行处理。
11.2 目的IP地址
OS从接收到的UDP数据报中将目的IP地址交给应用程序
11.3 UDP输入队列
来自不同客户的差不多同时到达的请求由UDP自动排队,接收到的UDP数据报以其接受顺序交给应用程序(不同于ARP的LIFO输入,UDP输出队列是FIFO)。
排队溢出可能会造成内核中的UDP模块丢弃数据报,然而应用程序并不知道其输入队列何时溢出,只是由UDP对超出数据报进行丢弃处理,并且没有任何信息告诉客户其数据报被丢弃。
11.4 限制本地IP地址
若进入的UDP数据报的目的地为服务器端口,那么在任何本地接口都可以接收到它。
服务器创建端点时可以将其中一个主机本地IP地址(包括广播地址)指定为端点的本地IP地址,例如这样就可以限制服务器在140.252.1.29处接收数据报,若以其他地址向该服务器发送一份数据报就会返回ICMP端口不可达差错,服务器永远看不到这份数据报。
注意:
- 系统应用程序可以重用相同的端口号
- 若为端点指定了IP地址,那么在匹配目的地址时就会优先匹配该IP地址,匹配不成功时才会使用带*的端点
11.5 限制远端IP地址
指定远端IP地址和端口号的副作用:自动选择本地地址
UDP服务器可以创建的3类地址绑定:
UDP模块在判断用哪个端点接收数据报时采用的顺序就是上图从上到下的顺序。
11.6 每个端口有多个接收者
多数系统某一时刻只允许一个程序端点与某个本地IP地址及UDP端口号相关联。而在支持多播的系统上,多个端点可以使用同一个IP地址和UDP端口号(应用程序需要告诉API可行,例如用-A标志来指明SO_REUSEADDR socket选项)
当UDP数据报到达的目的IP地址为广播地址或多播地址,且在目的IP地址(若本地IP地址含有*的话就可以匹配任意的目的IP地址)和端口号处有多个端点时,就会向每个端点传送一份数据报的复制。
12. 小结
- UDP报文段结构
- UDP检验和
- IP分片
- ICMP不可达差错(新的路径MTU发现功能中的一部分)
- 用Traceroute和UDP观察路径MTU的发现过程
- UDP和ARP之间的接口
- ICMP源站抑制差错报文