UDP协议
User Datagram Protocal ,用户数据报协议,它跟TCP协议不同,TCP协议是基于流的,发送的数据跟IP数据报个数无关。而UDP数据则直接封装成IP数据报发送(当然,如果UDP数据过长,会导致IP数据报分片发送)。所以UDP是简单的基于IP数据报的传输,而IP数据报的传输是不保证可到达,不保证传输顺序,所以UDP不提供任何的可靠性。
首部格式
- 「Source port」 源端口号,可选的,如果不用可全部置0.如果喜欢接收方能回复,则源端口号很重要,要不然别人也不知道回复哪个端口,我们知道,系统内核是通过端口号来映射应用程序的
- 「Destination port」 和「 「Source port」 一样的语义,通过指定接收方的端口号来指定特定应用程序接收到此UDP数据报
- 「Length」 指UDP数据报的长度,注意,包括「首部」 和 「数据报内容」 的总长度
- 「Check sum」 检验和,和 「IP」 检验和一样,不同的是UDP的检验和针对首部和内容全部计算得出检验和,关于「检验和」的计算方法,可以参考我前面的博客文章:IP协议
- 「Data octets」 UDP数据报内容,可以为空
UDP协议是一个很简单的协议,在RFC768里定义,也就3页的内容,好像是我看过的文字最少的RFC文档了。下面来看一些UDP相关的内容。
IP分片
前面已经说过,UDP协议是基于IP协议的简单封装,而IP协议对应的链路层有MTU的概念 ,即物理链路传输数据时有最大传输单元限制,这样当IP数据包长送的时候,会将MTU和当前的数据包长度进行比较,如果必要,则要进行IP分片传输。我们知道,以太网链路层的MTU是1500,则每次传输的最大数据不能超过1500字节(byte),如果超过了就要进行分片传输。
上图所描述的示例中,如果我们发送一个超过了MTU长度的UDP数据,比如1473字节,加上IP首部20字节和UDP首部8个字节,即1501字节,它比以太网链路层的MTU:1500多1个字节,所以要进行IP分片后传输。分片的第一个分组包含了UDP首部(8个字节)和UDP数据(1472)个字节。第二个分组只包含了UDP数据的最后一个字节内容。我们可以了解到,对于分片发送的UDP数据,只有第一个分组拥有UDP首部的信息,如果所有的分组中第一片分组丢失的话,则所有分组都要丢弃,因我们知道UDP首部中包含了重要的信息,如「Destination port」,如果不知道目的地端口号,则系统不知道将该数据交给哪个应用程序去处理。所以,利用UDP传输的应用程序,应该控制数据报的升序,尽量避免分片进行。
关于接收端在接收到一个IP数据报的分片数据时,如果进行重组,即把所有分片数据再次按顺序组合起来呢,这就要利用IP首部中一些字段标识,我们一起来复习下前面文章中的IP协议:
- Identification(唯一标识): 每一个IP数据报都要有唯一的标识字段,这样在分片和重组时不至于混淆两个完全不同的分片数据。就是说,一个IP数据报分片后,每个分片的IP首部中,该字段相同,这样接收端就知道这些分片来自一个数据报
- Flages(标志): 这个字段也是为IP数据报的分片和重组作用的。用于标识收到的分片后续是否还有分片待接收。1代表后续还有分处,0代表分片结束,所以最后一个分片该值为0
- Fragment offset(分片偏移):指当前分片数据在整体IP数据报中所处的偏移量,以8字节(64比特)为单位。由此可见,「identification」,「Flages」,「Fragment offset」这三个字段是为IP数据报分片和重组功能作用的字段
结束语
UDP相比TCP来说,是一个很简单的协议,在<<TCP/IP详解>>这本书中也可以感觉到,UDP只用了一章的篇幅,而TCP用了八章的篇幅介绍。但是,这并不能说UDP没有用武之地,直是UDP的简单,性能,也有很多它的应用的场景,像游戏协议,视频会议,我们希望数据快速传输,容忍偶尔丢失的场景,UDP正体现了它的用途。