UDP
UDP是一种对象数据报的传输层协议,它不提供可靠性,其数据报被封装在IP数据报中,封装格式如下图所示:
首部格式为
- 源端口号和目的端口号分表表示了发送进程和接收进程
- 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分片了。
- 发生ICMP不可达差错的另一种情况是,当路由器收到一份需要分片的数据报,而在IP首部又设置了不分片(DF)的标志比特。如果某个程序需要判断到达目的端的路途中最小MTU是多少—称作路径MTU发现机制,那么这个差错就可以被该程序使用。
- 理论上,UDP数据的最大长度为:65535-20字节IP首部长度-8字节UDP首部长度=65507。但是大多是实现都比这个值小,主要是受限于socket接口以及TCP/IP内核的限制。大部分系统都默认提供了可读写大于8192字节的UDP数据报。
- 当目标主机的处理速度赶不上数据接收的速度,因为接受主机的IP层缓存会被占满,所以主机就会发出一个ICMP源站抑制差错报文。