目录
0.前言
1.UDP协议格式
16位源端口和目的端口
16位UDP长度
16位校验和
2.UDP协议特点
无连接
不可靠
面向数据报
3.UDP的缓冲区
0.前言
首先,我们得明确一点,网络模型是分层的。自底向上分别是物理层、数据链路层、网络层、传输层、应用层。其中,应用层是用户直接使用的一层,也就是说,发送方的用户在应用层输入消息,接收方的用户在应用层接收消息。
我们还需要明确一点,发送方从应用层发送的数据需要自顶向下贯穿TCP/IP 协议栈,到达物理的设备上,通过物理的线路(可能有线,也可能无线)到达对方的物理设备上,然后自底向上贯穿TCP/IP 协议栈到达接收方的应用层。
发送方发送的消息自顶向下交付的时候,需要添加每一层的协议报头,接收方接收到的消息自底向上交付的时候,需要将自己这一层的协议报头分离,再向上交付。
铺垫:用户在应用层启动的一个个的应用程序其实就是一个个的进程,应用程序和应用程序之间进行通信,其实本质就是进程和进程之间进行通信。
从接收方的角度来看,我们很明确的可以知道,应用层的数据来自于传输层,那么问题来了,传输层如何将数据准确无误的交给应用层中对应的进程呢?这个时候就需要传输层的协议来保证了。而UDP协议就是传输层的一个常用的协议。
1.UDP协议格式
所谓协议,在代码实现上其实就是struct类型的数据,通信双方都定义相同的结构体类型的数据,这样一来,你发送的数据我能认识,我发送的数据你也能认识。
UDP是传输层的协议,传输层的协议是在操作系统内部实现的,所以操作系统源代码内部一定包含了UDP协议的相关内容。
Linux源代码中UDP协议相关字段:
我们可以将代码形象化,便得到了下面这张图:准确的说,下面这张图是UDP报文格式图。
其中,UDP协议报头中包含四个关键字段,分别是16位源端口地址、16位目的端口地址、16位UDP长度、16位UDP校验和。累计8字节,下面依次介绍这几个字段。
16位源端口和目的端口
我们从接收方的视角来看,应用层中的进程收到的数据一定是传输层交给他的,也就倒逼传输层需要正确的把数据交给对应的进程,应用层中启动的进程可能不止一个,这就要求传输层需要有一种能够找到对应进程的能力。
16位目的端口便提供了这种能力,通过16位目的端口,传输层就知道将解包之后的数据交给应用层中的哪个进程了。
同样,接收方和发送方的角色并不是固定的。可能接收方也要向发送方发送数据,发送数据的时候就需要知道接收的数据是谁发给我的,我才能向特定主机下的特定进程进行响应。而16位源端口便可告知对方该数据从哪里来的,这就是16位源端口的作用。
16位UDP长度
接收方传输层收到的是一个个UDP报文,向上交付的时候,不能把整个UDP报文交付给应用层,需要进行解包,将UDP报头分离下来之后,再交付给应用层。那么如何进行解包呢?这就需要使用到16位UDP长度了。
16位UDP长度表明了整个UDP报文的长度,包括报头和数据。由于UDP的协议报头是固定长度的8字节,而在前面我们知道了,协议是通信双方都认识的结构体类型,那我们只需要通过结构体类型的对象访问结构体中的16位UDP长度成员,不就可以得到整个UDP报文的长度了吗?再将整个UDP报文的长度减去定长8个字节的协议报头,就得到了有效载荷的长度,不就可以提取有效载荷了吗?这就是16位UDP长度的作用。
使用UDP协议的注意事项:
因为UDP的长度被规定为16位,也就是16个比特位从全0到全1的范围,换算下来大概 0kb ~ 64kb的空间。也就是说,使用UDP协议通信的最大范围就是64kb,并且这其中还包含UDP协议报头的长度。所以,如果传输的数据大一64kb,就需要在发送方的应用层手动分割数据包,并在接收方手动对数据包进行组装。
16位校验和
16位校验和也称为16位检验和。
什么是16位校验和?
16位校验和是一种用于检测报文在传输过程中是否发生错误的数据验证方法。具体来说,它涵盖了UDP报文头和数据部分,通过一种特定的算法计算得出,并附加在报文末尾。接收方在收到报文后,会重新计算校验和,并将其与报文中的校验和进行比较,以验证数据的完整性和正确性。
16位校验和的思想大概就是,发送方根据特定的方法提前通过要发送的数据计算出一个值,接收方接收到数据之后,再根据相同的方法通过接收到的数据计算出一个值,如果两个值一样说明数据传输的过程中没有出错,发送的数据就是要接受的数据。如果两个值不一样,就说明发送的数据和接收的数据不一致,接收方直接就丢弃了。
2.UDP协议特点
UDP协议具有无连接,不可靠,面向数据报的特点。
无连接
无连接指的是使用UDP协议进行通信时,通信双方只需要知道对方的IP地址和端口号就能直接进行数据的收和发,通信双方之间不需要建立连接。
这一点我们可以通过使用socket编程接口来理解。使用UDP协议时,客户端并不需要发起连接,服务器端也不需要获取连接,这一点和TCP是不同的。
不可靠
UDP协议的不可靠是指UDP协议并不保证报文准确无误的发送给对方,发送的数据包是否丢失、对方是否收到数据……UDP并不保证。所以UDP不像TCP那样拥有一系列的机制来保证可靠性。
UDP的不可靠特点,我们不能把他当成一个缺点。因为UDP在设计之初呢,就是为了通信双方能够更加快速的通信,必然导致UDP的设计比较简单,不具备支持可靠性的策略。
面向数据报
UDP面向数据报的特点指的就是上层交给UDP什么报文,UDP就发送什么报文,既不会拆分,也不会合并,接收方通过UDP协议就接收什么报文。整个通信的过程是基于数据报进行的。
3.UDP的缓冲区
UDP是传输层的协议,传输层的协议是在操作系统内部实现的,操作系统内部会为对应的协议分配一个接收缓冲区进行数据的接收,也会为对应的协议分配一个发送缓冲区进行数据的发送。
UDP协议没有真正意义上的发送缓冲区。因为UDP是面向数据报的协议,发送的数据直接通过sendto接口交给操作系统内核,由操作系统内核将数据交给网络层,直接就进行发送,所以UDP协议也不需要发送缓冲区。
UDP协议是有接收缓冲区的。UDP协议的接收缓冲区也仅仅是用来进行数据的接收,并不通过缓冲区提供可靠性保证;如果缓冲区满了,接收到的报文就会被丢弃。