UDP协议
之前笔者已经为大家介绍过了传输控制协议TCP,而对于设计非常复杂的TCP协议来说,今天我们所介绍的UDP协议可以说非常的简单。在读者看来,同样是传输层的UDP协议有着他的独特之处,他就好象只是为ip数据报服务增加了简单的功能。正是因为这样的简单设计才擦出了与TCP协议不一样的火花。
UDP协议的特点
UDP相对于TCP协议来说设计的非常简单,他相当于在ip数据报的基础上,仅仅添加了复用和分用的功能以及差错检验的功能,那么一起来看看UDP协议有什么样的特点:
上面的导图基本为我们总结清楚了udp协议的全部特点,但是其实udp也还拥有其他特点,比如由于他的报文首部只占8个字节,所以使发送数据时的开销大大降低。
当然,这里关于拥塞控制的问题势必影响到整个网络的情况,如果udp没有我们上面所说的拥塞功能,此时网络已经发生了拥塞,就会导致整个网络最后瘫痪。我们之前介绍tcp时我们发现tcp的机制并不是全部都体现在报头中的,所以在某些情况下,udp也需要在应用层自己实现拥塞控制,来减少数据的丢失。
UDP协议格式
- 源端口号:这个报文从那个进程来
- 目的端口号:要交给上层的哪个进程
- UDP长度:这里因为UDP的报文首部为8,所以使用总长度减去8字节就可以对报文进行解包
- UDP检验和:检验UDP用户数据报传送中是否有错,有错就丢失
UDP的首部检验
这里重点介绍一下UDP是如何进行首部检验的,因为这里的检验方式有一些特殊,让笔者觉得很有意思:
- UDP在进行首部检验时要向当前的UDP数据报添加12个字节的伪首部,之所以叫他伪首部是因为这部分并不是UDP数据报真正的首部。只是在进行检验时将这个伪首部临时添加到报文的首部,并不向下传递。UDP进行检验时与ip检验的方式很相似,但是不同的是,ip检验时只检验数据报的头部,而UDP会对整个数据报进行检验。
那么我们来看看UDP具体是如何检验数据的:
- 在发送方把全零填充到检验和字段,把伪首部和当前的用户数据报拼接起来,如果整个数据报现在长度不为偶数字节那么就添加一个全零字节,但是这个字节不发送
- 然后将报头排列成每行16位的比特位取反序列并计算出他们的和,将结构填充到检验字段并发送
- 接收端现在收到这个报文后添加伪首部和填充0,并和检验和一起相加,如果最后得出的结果为1就表示无错,不难看出这种检验方式虽然检验能力并不是很强,但是却体现了UDP协议简单的特点。
如图此检验方式不难理解,但是我们还提到了伪首部,那么一起看看这个伪首部有什么东西呢?
第三字段填充了一个字节的全零,第四字节的17表示UDP协议,UDP长度表示自己将要拼接UDP报文的总长度。当然了,我们之前讲解TCP时并没有讲解TCP怎么检验,其实TCP和UDP检验方式一样,只不过将第四字段的17换成6(tcp协议号为6),报文长度换成TCP的报文长度。
UDP的缓冲区
- UDP没有真正意义上的 发送缓冲区. 调用sendto会直接交给内核, 由内核将数据传给网络层协议进行后
续的传输动作 - UDP具有接收缓冲区. 但是这个接收缓冲区不能保证收到的UDP报的顺序和发送UDP报的顺序一致; 如果
缓冲区满了, 再到达的UDP数据就会被丢弃
UDP使用事项
UDP协议首部中有一个16位的最大长度.。也就是说一个UDP能传输的数据最大长度是64K(包含UDP首部)然而64K在当今的互联网环境下,是一个非常小的数字。如果我们需要传输的数据超过64K,就需要在应用层手动的分包,多次发送,并在接收端手动拼装
总结
UDP协议相对于TCP来说,设计简单且学习成本低,在特殊的场景下比TCP更有优势,这也就是为什么不删除UDP协议的原因。对于不可靠传输等一些选项读者并不需要把它理解为UDP的缺点,而更应该把它理解成一种特点。下篇博客我们就结合TCP和UDP来聊聊他们的差异。