一 UDP协议格式
- 16位源端口号:表示数据从哪里来。
- 16位目的端口号:表示数据要到哪里去。
- 16位UDP长度:表示整个数据报(UDP首部+UDP数据)的长度。
- 16位UDP检验和:如果UDP报文的检验和出错,就会直接将报文丢弃。
16位UDP检验和是什么?
UDP 协议的 16 位检验和确实是用于检验整个 UDP 报文的完整性。因为数据包经过层层封装,实际在传递时,是通过光缆光电信号传递,在数据传递过程中,可能会发生比特翻转,也就是二进制比特位颠倒,0->1和1->0。在传递过程中,如果遇到磁场波动或一些其他特殊情况会把高电平变为低电平,低电平变为高电平。但是收端是不知道会发生这些事情,为了防止于是双方就约定好了此字段。对传递的数据做校验,校验结果也分级别,第一级别是判断是否出错了,第二级别是能够识别出错了并且识别出哪里出错了。
实现第一级别的代价小,第二级别代价太大。本质都是通过引入冗余信息判断。UDP是实现的第一级别,使用CRC的方式完成,将数据经过计算,(设定一个两个字节变量,把所有数据的每个字节取出来往这个变量上累加,如果结果溢出,溢出部分舍弃。)计算完之后把这个值写入到协议中,收端收到后重复工作,用计算出来的结果和传来的做对比,如果一致,就说明没发生比特翻转。
UDP如何将报头与有效载荷进行分离?
UDP的报头当中只包含四个字段,每个字段的长度都是16位,总共8字节。因此UDP采用的实际上是一种定长报头,UDP在读取报文时读取完前8个字节后剩下的就都是有效载荷了。
UDP如何决定将有效载荷交付给上层的哪一个协议?
UDP上层也有很多应用层协议,因此UDP必须想办法将有效载荷交给对应的上层协议,也就是交给应用层对应的进程。
应用层的每一个网络进程都会绑定一个端口号,服务端进程必须显示绑定一个端口号,客户端进程则是由系统动态绑定的一个端口号。UDP就是通过报头当中的目的端口号来找到对应的应用层进程的。
1.1 面向数据报
应用层交给UDP多长的报文,UDP就原样发送,既不会拆分也不会合并,这就叫做面向数据报。
比如用UDP传输100个字节的数据:
如果发送端调用一次sendto,发送100字节,那么接收端也必须调用对应的一次recvfrom,接收100个字节;而不能循环调用10次recvfrom,每次接收10个字节。
1.2 UDP的缓冲区
UDP没有真正意义上的发送缓冲区。调用sendto会直接交给内核,由内核将数据传给网络层协议进行后续的传输动作。
UDP具有接收缓冲区。但是这个接收缓冲区不能保证收到的UDP报的顺序和发送UDP报的顺序一致;如果缓冲区满了,再到达的UDP数据就会被丢弃。
UDP的socket既能读,也能写,因此UDP是全双工的。
1.3 UDP使用注意事项
需要注意的是,UDP协议报头当中的UDP最大长度是16位的,因此一个UDP报文的最大长度是64K(包含UDP报头的大小)。然而64K在当今的互联网环境下,是一个非常小的数字。如果需要传输的数据超过64K,就需要在应用层进行手动分包,多次发送,并在接收端进行手动拼装。 UDP的优势就是快,因为不需要连接,所以如果主机都在同一个局域网内通信,使用UDP是一个不错的选择。