UDP 是面向数据报的传输层协议(TCP是面向字节流的协议)。面向报文的传输方式是指应用层交给UDP多长的报文,UDP就照样发送,即一次发送一个报文。
UDP不提供错误更正、重复消除、流量控制、拥塞控制。
UDP提供了错误检测
总的来说,UDP提供很少的功能来保证数据报传输,用户层必须处理这些问题。
UDP是面向数据报的协议,一个UDP数据报对应一个IP数据报。而TCP是 面向流的协议,IP数据报中的负载可能没有多大关系。
UDP 报文
端口号:
包含源端口号和目的端口号,用于标识主机上的特定进程。 如果报文不需要Reply,则源端口好可以设置为0.
Length:
UDP报文长度,单位为字节,一般来说,Length的最小值为8(即只有首部,没有负载)。一些IPv6的特殊情况除外。
UDP Checksum
UDP Checksum是一个端到端的检验和,Checksum覆盖了UDP 首部和数据报内容。(IPv4首部的Checksum只覆盖了首部)。在不发生NAT的情况下,UDP Checksum的检验和只在最终目的地时才进行检验。而IPv4首部的Checksum在每一条都要被修改(因为TTL被修改了)
UDP Checksum | IP Checksum |
---|---|
端到端的Checksum,覆盖了首部和负载 | 首部的Checksum, 不覆盖负载 |
不发生NAT的情况下,只在最终目的地才被Check | 每一跳都要进行Check和Modify,因为TTL发生了变化 |
UDP的伪首部
UDP-Lite
简易版的UDP。
我们知道,UDP协议的Checksum字段要么覆盖整个UDP报文(含首部和负载),要么为0。但是一些应用程序处于某些原因(尤其是在多播和广播时),希望只Checksum只覆盖UDP报文的一部分。为此,UDP-Lite被提出来。
UDP-Lite的协议号(在IP首部中protocol字段填入的值)为136,我们知道,TCP的协议号为9,UDP的协议号为17。 UDP-Lite可以视为与TCP、UDP平等的传输层协议。
UDP-Lite的报文首部与UDP报文有些差异。UDP中的Length字段被Checksum Coverage取代。(其实,UDP报文中的Length字段并不是必要的,因为UDP报文的长度可以根据IP首部的一些字段计算出来)
Checksum Coverage字段表明了Checksum覆盖的字节,如果为0,则标识Checksum覆盖了整个UDP-Lite报文。
路径MTU、IP的分片与重组
我们前面提到UDP是面向数据报的协议,应用层传给UDP多长的报文,UDP就原样发送。然而,链路层能够传输的帧大小是有上限的。因此,或者应用层对交给UDP的报文大小做出限制;或者IP层对UDP报文进行分片重组。才能保证报文得到正确的传输。
IP 分片
链路层能传输的帧大小是有限制的,且上限经常小与网络层的上限。 为了是网络层以上的协议脱离链路层相关,IP协议采用了分片、重组机制。
IP层需要发送数据报文时,首先要决定从那个接口发出这个报文、并得到该接口的MTU,当要发送的报文的大小大于接口MTU时,就会对数据报进行分片。对于IPv4来说,IP分片可以发生在源主机上,也可以发生在中间路由器上,但是对于IPv6而言,IP分片只能发生在源主机上。IP重组只发生在最终目的主机上
由于UDP不提供超时和重传机制使用UDP的应用程序必须处理这些问题,UDP很容易发生分片,如果某个分片在传输丢失,整个报文需要重传。
重组超时
当报文接收者接到第一个分片时,会启动一个定时器,定时器超时时如果还没接受到最后一个报文,就会想报文的发送这发送一个ICMPv4超时报文,来告诉报文的源发送者将放弃已接收到分片。ICMPv4超时报文中会包含第一个分片的内容。
UDP 路径MTU发现, PMTUD
传统的路径MTU探测使用ICMP PTB Message实现,ICMP PTB Message
能够获取路由路径可通过的最大报文Size。然而,ICMP PTB Message得到的醉经MTU对传输层是不可见的。目前有两种方法来帮助传输层(UDP)解决分配重组问题,
1. 通过 API调用,获取各个目的地的最大PMTU
2. IP层自己进行分片重组,而不在传输层、应用层进行分片重组。
UDP 报文大小限制
IP首部提供了2个字节用来表示IP数据报的大小(最大值为2^16-1, 即65535), 不过IP首部至少需要20字节,UDP首部需要8字节,因此UDP报文的理论最大值为65507。当然,这里只是理论值,使用UDP通信时,受到系统协议实现机制以及接收主机处理UDP数据报能力的限制,UDP报文的长度限制一般达不到65507这么大。
socket API 提供了一系列函数用于设置、查询UDP接收缓冲区和发送缓冲区的大小。
目前,主机一般被要求至少能接收576字节的UDP报文,因而很多程序在发送UDP时,设置了buff大小为512byte。