UDP协议
- UDP协议的位置
- UDP协议的特点
- UDP协议的格式
- UDP使用注意事项
UDP协议的位置
在网络套接字编程时用到的各种接口,是位于应用层和传输层之间的一层系统调用接口,这些接口是由系统提供的。我们可以通过这些接口来搭建上层应用,比如HTTP协议。我们经常说HTTP协议是基于TCP的,实际就是因为HTTP是在网络套接字编程时使用TCP相关接口的基础上搭建的。
基于UDP的应用协议有:
- NFS:网络文件系统
- TFTP:简单文件传输协议
- DHCP:动态主机配置协议
- BOOTP:启动协议(用于无盘设备启动)
- DNS:域名解析协议
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协议的格式如下图:
- 16位源端口号:指定发送方的应用程序使用的端口号
- 16位目的端口号:指定接收方的应用程序使用的端口号
- 16位UDP长度:表示整个数据报(UDP首部+UDP数据)的最大长度
- 16位UDP校验和:用于检测传输中是否发生错误。校验和字段可以选填,如果填写了,则需要进行校验和计算,否则置为0。
UDP如何将报头与有效载荷进行分离
UDP的报头中只含有四个字段,每个字段的长度都是16位,总共8字节,因此UDP实际上采用的是定长报头。UDP在读取报文时读取完前8个字节后剩下的就是有效载荷。
UDP如何决定将有效载荷交付给上层对应的协议?
UDP上层有很多的应用层协议,UDP必须想办法将有效载荷交给对应的上层协议,也就说交给应用层对应的进程。
应用层的每一个网络进程都会绑定一个端口号,服务端进程必须显示绑定一个端口号,客户端进程则是由系统动态绑定一个端口号。UDP就是通过报头中的目的端口号来找到对应的应用层进程的。
内核中采用了哈希的方式维护了端口号和进程ID之间的映射关系,因此传输层可以通过端口号找到对应的进程ID,进而找到对应的应用层进程。
UDP使用注意事项
需要注意的是,UDP协议报头当中的UDP最大长度是16位的,因此一个UDP报文的最大长度是64K(包含UDP报头的大小)。
然而64K在当今的互联网环境下,是一个非常小的数字。如果需要传输的数据超过64K,就需要在应用层进行手动分包,多次发送,并在接收端进行手动拼装