# UDP

UDP是一种对象数据报的传输层协议，它不提供可靠性，其数据报被封装在IP数据报中，封装格式如下图所示：

![](https://1111800802-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L9rgYC6PUIj4mlO7_pn%2F-LDZS-yElRbis9qdjN9s%2F-LDZSEASNRVxeNHXq5ce%2F201210212125538830.jpg?generation=1527472528443462\&alt=media)

首部格式为

![](https://1111800802-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L9rgYC6PUIj4mlO7_pn%2F-LDZS-yElRbis9qdjN9s%2F-LDZSEAVSP4dvDpk5AG_%2F201210212125533257.jpg?generation=1527472528770940\&alt=media)

* 源端口号和目的端口号分表表示了发送进程和接收进程
* UDP长度字段包括了UDP首部和UDP数据的字节长度
* UDP检验和覆盖了UDP首部和UDP数据（IP首部检验和只覆盖了IP首部，不覆盖数据报中的任何数据）
* UDP数据报的长度可以为奇数字节，但是检验和算法是把若干个16bit字相加。解决方法是必要时在最后增加填充字节0，这只是为了检验和的计算。UDP数据报和TCP段都包含一个12字节长的伪首部，它是为了计算检验和而设置的。伪首部包含IP首部一些字段。

## IP分片

以太网和802.3对数据帧的长度都有一个限制，其最大值分别是1500和1492个字节。链路层的这个特性称作MTU。不同类型的网络大多数都有一个上限。如果IP层有一个数据要传，且数据的长度比链路层的MTU还大，那么IP层就要进行分片（fragmentation），把数据报分成若干片，这样每一个分片都小于MTU。当IP数据报被分片后，每一片都成为一个分组，具有自己的IP首部，并在选择路由时与其他分组独立。

把一份IP数据报进行分片以后，由到达目的端的IP层来进行重新组装，其目的是使分片和重新组装过程对 运输层（TCP/UDP）是透明的。由于每一分片都是一个独立的包，当这些数据报的片到达目的端时有可能会失序，但是在IP首部中有足够的信息让接收端能正确组装这些数据报片。

尽管IP分片过程看起来透明的，但有一点让人不想使用它：即使只丢失一片数据也要重新传整个数据报。

why？因为IP层本身没有超时重传机制------由更高层（比如TCP）来负责超时和重传。当来自TCP报文段的某一片丢失后，TCP在超时后会重发整个TCP报文段，该报文段对应于一份IP数据报（而不是一个分片），没有办法只重传数据报中的一个数据分片。

使用UDP很容易导致IP分片，TCP试图避免IP分片。那么TCP是如何试图避免IP分片的呢？其实说白了， 采用TCP协议进行数据传输是不会造成IP分片的，因为一旦TCP数据过大，超过了MSS，则在传输层会对 TCP包进行分段（如何分，见下文！），自然到了IP层的数据报肯定不会超过MTU，当然也就不用分片了 。而对于UDP数据报，如果UDP组成的IP数据报长度超过了1500，那么IP数据报显然就要进行分片，因为 UDP不能像TCP一样自己进行分段。

MSS（Maxitum Segment Size）最大分段大小的缩写，是TCP协议里面的一个概念

* 1）MSS就是TCP数据包每次能够传输的最大数据分段。为了达到最佳的传输效能TCP协议在

  建立连接的时候通常要协商双方的MSS值，这个值TCP协议在实现的时候往往用MTU值代替（需要减去IP

  数据包包头的大小20Bytes和TCP数据段的包头20Bytes）所以往往MSS为1460。通讯双方会根据双方提

  供的MSS值得最小值确定为这次连接的最大MSS值。
* 2）相信看到这里，还有最后一个问题：TCP是如何实现分段的呢？其实TCP无所谓分段，因为每

  个TCP数据报在组成前其大小就已经被MSS限制了，所以TCP数据报的长度是不可能大于MSS的，当然由

  它形成的IP包的长度也就不会大于MTU，自然也就不用IP分片了。

![](https://1111800802-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-L9rgYC6PUIj4mlO7_pn%2F-LDZS-yElRbis9qdjN9s%2F-LDZSEAbdKhNjfhsNySL%2F201210212125545110.jpg?generation=1527472529094692\&alt=media)

* 发生ICMP不可达差错的另一种情况是，当路由器收到一份需要分片的数据报，而在IP首部又设置了不分片（DF）的标志比特。如果某个程序需要判断到达目的端的路途中最小MTU是多少—称作路径MTU发现机制，那么这个差错就可以被该程序使用。
* 理论上，UDP数据的最大长度为：65535-20字节IP首部长度-8字节UDP首部长度=65507。但是大多是实现都比这个值小，主要是受限于socket接口以及TCP/IP内核的限制。大部分系统都默认提供了可读写大于8192字节的UDP数据报。
* 当目标主机的处理速度赶不上数据接收的速度，因为接受主机的IP层缓存会被占满，所以主机就会发出一个ICMP源站抑制差错报文。
