UDP是一个很简单的协议定义它的rfc768只有短短三页作为一个传输层协议UDP只在网络层协议如IPV4/IPV6上做了一个简单的扩展

UDPHeader由四个字段组成Src Port(2 Bytes), Dest Port(2 Bytes), Checksum(2 Bytes), Length(2 Bytes)相比于IP协议UDP增加了

  • 端口
  • checksum

端口机制使得在同一个IP地址下可以同时有多个使用UDP的应用互不干扰Checksum则为数据提供了简单的错误发现机制

值得注意的是Checksum计算的时候UDPHeader和包内容之前还额外的包含了IPPseudo Header里面主要包含了IP Header中的Src Addr, Dest Addr, Protocal NumberData Length等信息 这是因为包的接收方需要验证包的源地址和包的目标地址在网络传输的过程中没有发生损坏以确保未受到期望之外的数据包由于上层的协议需要依赖于下层的数据这是一种违反分层的做法(Layer Violation) IPV4 Header本身就包含了ChecksumUDPChecksum尽管被推荐使用在性能敏感的情况下用户也可以将UDPChecksum设置成0来关闭校验IPV6header中没有Checksum因此使用IPV6协议的UDP必须包括Checksum

考虑到在某些场景下可能只需要对UDP内容的一部分数据进行校验所以产生了UDP Lite协议 UDP lite协议去掉了多余的Length字段UDP Length可以通过IPLength减去IP头的长度算出来加入了checksum coverage字段来设置需要Checksum的数据长度

UDP由于无连接的特性适合需要BroadcastMulticast的场景

UDP的使用中应额外关注IP FragmentationUDP没有自动的措施防止Fragmentation 网络中各段的MTU是不一样的假设UDP的包+IP header超过了某段链路MTU如果IPDFDon't Fragment)字段没有设置UDP就可能被分成若干个IP Fragment发送 先到的Fragment会被接收方缓存经过一段超时(通常为30s或者60s如果全部的fragment还没有到达buffer中的数据会被完全丢弃可能向发送方发送一条ICMP消息告知包内容已被丢弃 如果这些Fragment中有任意一个在传输过程中丢失或错误传输因为UDP没有重传和纠错机制这个UDP包会被整体丢弃影响网络性能 尽管UDP本身支持2^16 - 1 = 65535字节大小的长度但大部分的UDP包设置在1500 Bytes以下以避免分片1500 Bytes这个边界是因使用广泛的Ethernet限制的

IPDF字段设置的时候经过支持PMTUUD(Path MTU Unit Discovery)的路由的时候路由会丢弃超过MTU大小的包并回传一条ICMP消息告诉发送方当前路径的MTU 如果发送方接受到这条ICMP消息会根据消息内容记录MTU并调整UDP包的大小

UDP使用简单方便开销小适合对性能要求高数据准确性要求较低的场景使用如流媒体视频等但缺乏重传Congestion ControlFlow Control等机制需要上层应用自己实现