【Linux 29】传输层协议 - UDP
文章目录
- 🌈 一、端口号概念
- ⭐ 1. 端口号的作用
- ⭐ 2. 使用五元组唯一标识一个通信
- ⭐ 3. 协议号 VS 端口号
- ⭐ 4. 知名端口号
- ⭐ 5. 端口号与进程的关系
- ⭐ 6. netstat 查看网络状态
- 🌈 二、UDP 协议
- ⭐ 1. UDP 协议格式
- ⭐ 2. UDP 协议特点
- ⭐ 3. 面向数据报概念
- ⭐ 4. UDP 的缓冲区
- ⭐ 5. 使用 UDP 协议时的注意事项
- ⭐ 6. 基于 UDP 实现的应用层协议
🌈 一、端口号概念
⭐ 1. 端口号的作用
- 端口号 port 用来标识一个主机上进行网络通信的唯一的一个进程。
- 端口号属于传输层的概念,在传输层协议的报头中会添加与端口号相关的字段。
- 当主机从网络上获取到数据后,需要自底向上进行数据的交付,而这个数据最终应该交给上层的哪个应用处理程序 (进程),则由该数据当中携带的端口号来决定。
- 将从网络中获取到的数据向上交付时,在传输层会提取出该数据所对应的目的端口号,从而确定该数据应该交给当前主机中的哪一个服务进程。
⭐ 2. 使用五元组唯一标识一个通信
- 在 TCP / IP 协议中,使用 { 源 IP地址,源端口号,目的 IP 地址,目的端口号,协议号 } 这样的五元组来唯一标识一个通信。
- 当多台客户端主机同时访问服务器时,这些客户端主机上又可能存在着 n 个客户端进程,这些进程都在访问同一台服务器。
- 服务器就是通过五元组来识别一个通信,服务器会分别提取出五元组的某部分内容进行识别,识别过程如下:
- 提取 目的 IP 地址 和 目的端口号,判断该数据是否是发送给当前服务进程。
- 提取 协议号,为该数据提供该协议号所对应的协议服务。
- 提取 源 IP 地址 和 源端口号,将其作为响应数据的 目的 IP 地址和 目的端口号,将响应结果返回给对端主机。
⭐ 3. 协议号 VS 端口号
- 协议号:存在于 IP 报头中,长度为 8 位,作用于传输层和网络层之间。标识了数据包所携带的数据使用的是什么协议,以便于让目的主机的 IP 层知道应该将该数据交给传输层的哪个协议处理。
- 端口号:存在于 UDP 和 TCP 报头中,长度为 16 位,作用于应用层和传输层之间。用于唯一的标识主机上的一个进程。
⭐ 4. 知名端口号
- 某些服务器由于非常常用,为了使用方便,它们的端口号一般都是固定的。
- 客户端在访问时可以不知道这些知名服务器的端口号,在访问某个服务时直接自动添加上对应端口号。
- 例:在访问 SSH 服务时,客户端会自动加上 22 号端口,客户端相信 SSH 的端口号一定是 22。
- 在编写需要使用到端口号的程序时,应避免绑定这些知名端口号 (一般也不让绑)。
知名服务器 | 所使用的端口号 |
---|---|
SSH 服务器 | 22 号端口 |
FTP 服务器 | 21 号端口 |
TELENT 服务器 | 23 号端口 |
HTTP 服务器 | 80 号端口 |
HTTPS 服务器 | 443 号端口 |
查看知名端口号
- 可以通过查看
/etc/services
文件中的内容查看知名端口号。 - 该文件中存储的是网络服务名和与他们对应使用的端口号及协议。
- 该文件中的每一行都对应着一种服务,每行有 4 个字段,分别表示:
- 服务名称 、该服务所用的端口号、协议名称、别名。
⭐ 5. 端口号与进程的关系
- 一个进程可以绑定多个端口号,这些端口号都能唯一标识一个进程。
- 一个端口号绝对不能被多个进程绑定,如果这么做了,端口号就不能唯一的标识一个进程。
通过哈希表维护端口号与进程的关系
- 在操作系统内部维护着一张用来维护端口号与进程 PCB 关系的哈希表。
- 在这张哈希表中,key 是 端口号,value 是进程 PCB 所对应的地址。通过端口号就可以找到对应进程 PCB 的地址。
- 所谓的绑定 (bind) 就是将端口号与进程 PCB 的地址构建在这张哈希表中。
- 端口号作为唯一的 key 值,它是不能被多个进程绑定的。
- 一个 key 只能有一个 value,而一个 value 可以作为多个 key 的 value。
⭐ 6. netstat 查看网络状态
netstat
指令用于查看网络状态
netstat -选项
1. netstat 指令的常见选项
选项 | 说明 |
---|---|
n | 拒绝显示别名,将能用数字显示的全部转换成数字 |
l | 列出处于 LISTEN 监听状态的服务 |
p | 显示建立相关链接的程序名 |
t | 显示 tcp 相关的选项 |
u | 显示 udp 相关的选项 |
a | 显示所有选项,默认不显示 LISTEN 相关 |
2. 查看 TCP 相关的网络信息
- 一般会使用
nltp
的选项组查看 TCP 相关的网络信息。
3. 查看 UDP 相关的网络信息
- 一般会使用
nlup
的选项组查看 UDP 相关的网络信息。
4. 网络状态信息的各字段说明
- Proto:协议名、Local Address:源 IP 地址 和 源端口号、Foreign Address:目的 IP 地址 和 目的端口号。
🌈 二、UDP 协议
⭐ 1. UDP 协议格式
- 由于传输层协议的端口号是 16 位的,因此在应用层查看到的端口号大部分都是 16 位。
- UDP 报头是一个结构体,因此 UDP 协议报头中的每一个字段都是这个结构体中的成员。
struct udphdr
{__be16 source; // 16 位源端口号__be16 dest; // 16 位目的端口号__be16 len; // 16 位 UDP 正文长度__sum16 check; // 16 位 UDP 检验和
};
UDP 报头中各字段标识的含义
- 16 位源端口号:记录数据从哪来。
- 16 位目的端口号:记录数据要到哪去。
- 16 位 UDP 报文长度:记录整个数据报 (UDP 首部 + UDP 数据正文) 的长度。
- 16 位 UDP 检验和:用于保证报文的完整性,如果 UDP 报文的检验和出错,则直接将报文丢弃。
⭐ 2. UDP 协议特点
- 无连接:只要知道对端的 IP 地址和端口号即可进行数据传输,无需建立连接。
- 不可靠:没有确认机制、没有重传机制。如果出现网路故障导致丢包了,UDP 协议层也不会给应用层返回错误信息。
- 面向数据报:不能灵活的控制读写数据的次数和数量,报文与报文之间界限明确,只需要对读到的报文进行序列化和反序列化。
⭐ 3. 面向数据报概念
- 应用层交给 UPD 协议多长的报文,UDP 就发送多长的报文。UDP 不会拆分也不会合并报文。
- 例:如果发送端调用一次 sendto 发送 100 个字节,接收端也必须调用对应的一次 recvfrom 接收 100 个字节;而不能循环调用 10 次 recvfrom,每次接收 10 个字节。
⭐ 4. UDP 的缓冲区
- UDP 没有真正意义上的缓冲区,调用 sendto 函数会直接将数据包交给内核,由内核将数据传给网络层协议进行之后的传输动作。
- UDP 具有接收缓冲区,但这个接收缓冲区并不能保证收到的 UDP 报文的顺序和发送的 UDP 报文的顺序一致;如果这个缓冲区被填满了,之后到达的 UDP 报文就会被丢弃。
- UDP 是全双工的,UDP 的 socket 可以进行读、写操作。
为什么 UDP 会有接收缓冲区
-
UDP 接收缓冲区的作用就是暂存接收到的报文,方便上层应用读取。
-
UDP 如果没有接收缓冲区,上层就必须及时的将 UDP 获取的报文读走,稍微慢一点之后 UDP 从底层读取上来的报文数据就得被丢弃。
- 虽然 UDP 不保证可靠性,但也不能大面积的丢包。
-
当报文从一台主机被传输到另一台主机的过程中,会消耗主机资源和网络资源。如果此时 UDP 收到的报文因为上一条报文没有被及时读走而被丢弃,这被消耗的主机和网络资源可不会回来。
⭐ 5. 使用 UDP 协议时的注意事项
- 由于 UDP 报头中的用来记录 UDP 报文最大长度的字段只有 16 位,因此一个 UDP 报文的最大长度为 64 KB。
- 如果需要传输的数据长度超过了 64KB,就需要再应用层进行手动分包,多次发送,然后再在接收端进行手动拼接。
⭐ 6. 基于 UDP 实现的应用层协议
基于 UDP 实现的应用层协议 | 说明 |
---|---|
NFS | 网络文件系统 |
TFTP | 简单文件传输协议 |
DHCP | 动态主机配置协议 |
BOOTP | 启动协议 (用于无盘设备的启动) |
DNS | 域名解析协议 |