文章目录
UDP协议格式
- 16位源端口号:表示数据从哪里来。
- 16位目的端口号:表示数据要到哪里去。
- 16位UDP长度:表示整个数据报(UDP首部+UDP数据)的长度。
- 16位UDP检验和:如果UDP报文的检验和出错,就会直接将报文丢弃
端口号大部分都是16位的,因为传输层协议当中的端口号就是16位的
UDP如何将报头与有效载荷进行分离?
- UDP的报头当中只包含四个字段,每个字段的长度都是16位,总共8字节。UDP采用的是一种定长报头,UDP在读取报文时,读取完前8个字节后剩下的就都是有效载荷了。
UDP如何将有效载荷交付给上层?
UDP上层也有很多应用层协议,因此UDP必须想办法将有效载荷交给对应的上层协议,也就是交给应用层对应的进程。
应用层的每一个网络进程都会绑定一个端口号,服务端进程必须显示绑定一个端口号,客户端进程则是由系统动态绑定的一个端口号。UDP是通过报头当中的目的端口号来找到对应的应用层进程的
UDP报头实际就是一个位段类型
struct udp_header {
unsigned int src_port:16; // 源端口号
unsigned int dst_port:16; // 目的端口号
unsigned int udp_len:16; // UDP长度
unsigned int udp_chk:16; // 检验和
};
UDP数据封装:
- 当应用层将数据交给传输层后,在传输层就会创建一个UDP报头类型的变量,然后填充报头当中的各个字段,此时就得到了一个UDP报头。
- 此时操作系统再在内核当中开辟一块空间,将UDP报头和有效载荷拷贝到一起,此时就形成了UDP报文
UDP数据分用:
- 当传输层从下层获取到一个报文后,就会读取该报文的钱8个字节,提取出对应的目的端口号。
通过目的端口号找到对应的上层应用层进程,然后将剩下的有效载荷向上交付给该应用层进程。
UDP协议的特点
- 无连接:知道对端的IP和端口号就直接进行数据传输,不需要建立连接。
- 不可靠:没有确认机制,没有重传机制;如果因为网络故障该段无法发到对方,UDP协议层也不会给应用层返回任何错误信息。
- 面向数据报:不能够灵活的控制读写数据的次数和数量。
注意: 报文在网络中进行路由转发时,并不是每一个报文选择的路由路径都是一样的,因此报文发送的顺序和接收的顺序可能是不同的。
面向数据报
- 应用层交给UDP多长的报文,UDP就原样发送,既不会拆分,也不会合并,这就叫做面向数据报。
例如:用UDP传输100个字节的数据,如果发送端调用一次sendto,发送100字节,那么接收端也必须调用对应的一次recvfrom,接收100个字节;而不能循环调用10次recvfrom,每次接收10个字节
UDP的缓冲区
- UDP没有真正意义上的发送缓冲区。调用sendto会直接交给内核,由内核将数据传给网络层协议进行后续的传输动作。
- UDP具有接收缓冲区。但是这个接收缓冲区不能保证收到的UDP报的顺序和发送UDP报的顺序一致;如果缓冲区满了,再到达的UDP数据就会被丢弃。
- UDP的socket既能读,也能写,因此UDP是全双工的
如何理解UDP要有接收缓冲区?
如果UDP没有接收缓冲区,那么就要求上层及时将UDP获取到的报文读取上去,如果一个报文在UDP没有被读取,那么此时UDP从底层获取上来的报文数据就会丢弃。
一个报文从一台主机传输到另一台主机,在传输过程中会消耗主机资源和网络资源。如果UDP收到一个报文后是因为上次收到的报文没有被上层读取,从而丢弃一个报文,就是浪费了主机资源和网络资源。
UDP本身是会维护一个接收缓冲区的,当有新的UDP报文到来时就会把这个报文放到接收缓冲区当中,此时上层在读数据的时就从这个接收缓冲区当中进行读取,如果UDP接收缓冲区当中没有数据,那上层在读取时就会被阻塞
因此UDP的接收缓冲区的作用:将接收到的报文暂时的保存起来,供上层读取
基于UDP的应用层协议
- NFS:网络文件系统。
- TFTP:简单文件传输协议。
- DHCP:动态主机配置协议。
- BOOTP:启动协议(用于无盘设备启动)。
- DNS:域名解析协议。