前言
UDP是一个面向数据报的传输层协议,进程的每个输出操作都正好产生一个UDP数据报,并封装成一份待发送的IP数据报。这和面向流字符的TCP协议不同,在TCP中应用程序产生的全体数据与真正发送的单个IP数据报可能没什么关系。UDP数据报封装成一份IP数据报的格式,如下图所示。
UDP首部
UDP校验和
UDP校验和覆盖UDP的首部和数据部分。需要注意的是,IP首部的校验和,它只覆盖IP的首部,并不覆盖IP数据报内的任何数据。
UDP和TCP在首部当中都有覆盖首部和数据的校验和。
对于UDP来说,校验和是可选的,而TCP的校验和是必需的。
尽管UDP检验和的基本计算方法与IP首部检验和计算方法相类似(16 bit字的二进制反码和),但是它们之间存在不同的地方。
首先, UDP数据报的长度可以为奇数字节,但是检验和算法是把若干个16 bit字相加的;解决方法是必要时在最后增加填充字节0,这只是为了检验和的计算(也就是说,填充的字节是不被传送的);
其次,UDP数据报和TCP段都包含一个12字节长的伪首部,它是为了计算检验和而设置的。伪首部包含IP首部一些字段。其目的是让UDP两次检查数据是否已经正确到达目的地(例如, IP没有接受地址不是本主机的数据报,以及I P没有把应传给另一高层的数据报传给UDP)。UDP数据报中的伪首部格式如上图所示。
如果发现校验和出错,那就把UDP数据报丢弃,并不产生ICMP报文,这和IP是一样的情况的;
IP数据报分片
链路层是要限制每个以太网帧的长度的;每当IP层接收到一个要发送的IP数据报时,它要判断应该发送给本地的哪个端口(选路),并查询该端口获得MTU。
IP把MTU和IP数据报的长度进行比较,如果需要则分片;需要注意的是,不只是发送端会进行分片,中间的路由器也可能会发生分片(比如,两个网络的连接路由);所以,已经分片过的数据报,也可能会被再次分片(可能不止一次)。
把一份IP数据报分片以后,只有到达目的端的IP层才进行重新组装;
上图中的,16bit标识字段对于每个IP数据报来说,都具有唯一的值,该值在IP数据报被分片时被复制到每个分片中。
3bit标志:该字段中的一个bit用于表示还有“更多的片”,除了最后的那片外,其他的每片,该字段的这个bit都是1;
13bit的片偏移:指该片偏移原始数据报开始处的位置;
3bit标志还有个比特被称为“不分片”位,如果将这一比特置为1,IP将不对数据报进行分片。相反把数据报丢弃并发送一个ICMP差错报文(“需要进行分片但设置了不分片比特”)给起始端;
当IP数据报被分片后,每一片都成为一个分组,具有自己的IP首部,并在选择路由时与其他分组独立;
尽管IP分片过程看起来是透明的,但有一点让人不想使用它:即使只丢失一片数据也要重传整个数据报。为什么会发生这种情况呢?
因为IP层本身没有超时重传的机制——由更高层来负责超时和重传(TCP有超时和重传机制,但UDP没有。一些UDP应用程序本身也执行超时和重传)。
当来自TCP报文段的某一片丢失后,TCP在超时后会重发整个TCP报文段,该报文段对应于一份IP数据报。没有办法只重传数据报中的一个数据报片;
------------------------------------------------------
另外需要解释几个术语: IP数据报是指IP层端到端的传输单元(在分片之前和重新组装之后),分组是指在IP层和链路层之间传送的数据单元。一个分组可以是一个完整的IP数据报,也可以是IP数据报的一个分片。