Linux——传输层协议UDP
一、传输层
“负责数据能够从发送端传输到接收端” 是传输层最核心、最根本的任务。
- 网络层 负责的是 “主机到主机” 的通信(比如,从你的电脑到一台遥远的服务器)。它只关心把数据包送到目标IP地址。
- 传输层 则更进一步,负责 “进程到进程” 或 “应用到应用” 的通信。你的电脑上可能同时运行着浏览器、微信、音乐播放器等多个程序,它们都在通过网络收发数据。传输层要确保浏览器的数据交给服务器的Web服务,而不是别的。
如何实现?—— 通过端口号
1.再谈端口号
传输层使用 端口号 来标识主机上的不同应用程序。
- 发送端:知道目标服务器的IP地址和目标应用程序的目标端口号(如Web服务通常是80/443)
- 接收端:通过IP地址到达目标服务器后,再通过数据包中的目标端口号,把这个数据交给服务器的目标应用程序

在TCP/IP协议中,用 “源IP”,“源端口号”,“目的IP”,“目的端口号”,“协议号” 这样一个五元组来标识一个通信。
- 源IP和目的IP确定了需要传输的两台主机
- 源端口和目的端口确定了哪两个程序之间的数据传递
- 协议号决定了传输协议是采用UDP还是TCP处理数据

2.端口号划分
端口号长度是16位,因此端口号的范围就是 0~2^16
- 0 - 1023:知名端口号, HTTP, FTP, SSH等这些广为使用的应用层协议,他们的端口号都是固定的
- 1024 - 65535:操作系统动态分配的端口号,客户端程序的端口号,就是由操作系统从这个范围分配的
以下是一些常用的服务器的固定端口号:
- ssh服务器,使用22端口
- ftp服务器,使用21端口
- telnet服务器,使用23端口
- http服务器,使用80端口
- https服务器,使用443端口
我们自己写一个程序使用端口号时,要避开这些知名端口号
3.端口号和进程的关系
一个进程是否可以绑定多个端口号?
可以。
一个进程可以创建多个网络套接字(打开多个文件描述符),并将每个套接字(文件描述符)绑定到不同的端口号上。
一个端口号是否可以被多个进程绑定?
通常情况下不行,但在特定条件下可以。
分情况讨论:
情况 A:默认情况 —— 不允许
在绝大多数情况下,操作系统不允许两个进程绑定到同一个端口号。如果你尝试这样做,第二个进程在调用 bind() 时会失败,并得到一个类似 “Address already in use” 的错误。
原因:
当数据包到达时,操作系统需要通过 IP地址 + 端口号 + 协议(TCP/UDP) 这个三元组来唯一确定应该将数据交付给哪个进程的哪个套接字。
如果两个进程绑定了同一个端口,操作系统将无法做出唯一决策,导致数据混乱。
情况 B:特殊情况 —— 允许
在某些特定技术手段下,可以实现多个进程绑定同一个端口。
最常见的实现方式:SO_REUSEADDR / SO_REUSEPORT 套接字。通过设置套接字选项,可以允许多个套接字绑定到相同的地址和端口。
- SO_REUSEADDR:主要用于解决“TIME_WAIT”状态下的端口快速重用问题。在某些系统(如 Windows)和特定条件下,它也能允许多个绑定。
- SO_REUSEPORT(Linux 3.9+ 引入):明确设计用于允许多个进程(或线程)绑定到完全相同的 IP 地址和端口号。操作系统内核会在内核层面进行负载均衡,将传入的连接均匀地分配给这些监听了同一端口的进程。
总结
一般情况下,系统交付数据时,需要通过端口号找到唯一进程。所以,一个进程可以绑定多个端口号,一个端口号不能被多个进程绑定。
4.常用命令
查看知名端口号
cat /etc/services

我们使用端口号时要避开这些端口号
查看网络状态
netstat [选项]
- n:拒绝显示别名,能显示数字的全部转化成数字
- l:仅列出有在listen的服务状态
- t:仅显示tcp选项
- u:仅显示udp相关选项
- a:显示所有选项
- p:显示建立连接的相关程序名

查看服务器进程id
pidof 进程名

二、UDP协议
1.UDP协议端格式

UDP首部长度:固定为8字节,包含4个16位字段。
- 16位源端口号:确定了数据发送的起始端口
- 16位目的端口号:确定了数据发送的终点端口
- 16位UDP长度:定义了整个UDP数据报的长度(首部+数据)
- 16为UDP检验和:判断传输过程中是否发生错误
UDP如何将报头与有效载荷分离
UDP报头固定8字节,在每次读取的时候读取8字节即可,剩下的就是有效载荷,这样就完成了报头与有效载荷分离
UDP数据封装
传输层在接受到应用层的数据后(应用层数据),对应用层数据添加报头进行封装(8字节报头),最终形成数据报(报头+应用层数据)
2. UDP特点
- 无连接:不需要建立连接,只需要知道目的端口和IP就可以传输
- 不可靠:没有确认机制,不会进行握手操作,若数据丢失,也没有重传机制
- 面向数据报:发送只能以一份一份数据报进行发送,接收只能一份一份数据报进行接收,且有最大受限大小(约 64KB(包含头部))
面向数据报
应用层交给UDP多长的报文,UDP原样发送,既不拆分,也不合并,一次性将内核缓冲区中的数据全部发送出去,接收端会一次性接收发送端发送的所有数据,不能分多次接收。
例如:发送方一次性发送100个字节的数据,那么接收方也需要一次性接收100 字节的数据。如果超过接收缓冲区大小,多余部分直接丢弃
3. UDP缓冲区
在TCP协议中,send/sendto、recv/recvfrom本质上是一个拷贝接口,它们前者负责将应用层的数据拷贝到发送缓冲区,后者负责将数据从接收缓冲区拷贝到应用层。在两个缓冲区中的数据由TCP的内部代码进行发送和接收,用户只负责将数据放入或拿出这两个缓冲区。
而在UDP协议中又不太一样:
发送缓冲区
- 无真正的发送缓冲区:UDP协议本身并不维护一个发送缓冲区。当应用程序调用sendto发送数据时,数据会被直接封装成UDP数据报,然后交给网络层(IP层)处理。
- 可能因网络层拥堵而阻塞:虽然UDP本身没有发送缓冲区,但在数据交给网络层后,如果网络层无法立即发送,则可能会阻塞后续的发送操作。但是,UDP不会像TCP那样进行重传或拥塞控制,它只是尽可能快地发送。
为什么udp不需要发送缓冲区呢?
我们可以从UDP的工作方式来理解。
1.UDP的发送过程:
- 当应用程序调用sendto发送UDP数据报时,UDP不会对数据进行缓存,而是立即将数据封装成IP数据报并发送到网络。
- 如果应用程序发送数据的速度超过了网络接口的处理能力,UDP不会像TCP那样将数据缓存在发送缓冲区中,而是直接丢弃数据。
2.UDP的无连接和不可靠特性:
- 由于UDP不需要保证可靠性,因此它不需要维护发送缓冲区(存储已发送但未确认的数据)。
- 同时,UDP是无连接的,所以它不需要维护连接状态,包括发送缓冲区。
3.TCP的对比:
- TCP是面向连接的、可靠的协议。它使用发送缓冲区来存储已发送但尚未被确认的数据,以便在超时或收到重复确认时进行重传。
- TCP还需要实现流量控制和拥塞控制,这些都需要缓冲区来配合。
4.UDP的简单性:
- UDP的设计目标就是简单高效,省略发送缓冲区减少了UDP的实现复杂性和内存开销。
5.实际影响:
- 由于没有发送缓冲区,应用程序调用sendto时,数据会立即被送出(或者因为某些原因被丢弃),而不会在UDP层被缓存。这意味着如果网络条件不好,数据包可能会被大量丢弃,而应用程序可能无法及时得知。
因此,UDP不需要发送缓冲区是因为其无连接和不可靠的特性所决定的。它不需要重传,也不需要流量控制,所以没有必要缓存发送的数据。
接收缓冲区
- 存在接收缓冲区:UDP协议在内核中维护了一个接收缓冲区,用于存储接收到的UDP数据报。每个UDP socket都有自己独立的接收缓冲区。
- 不保证顺序:由于UDP数据报是独立传输的,可能因为网络路径不同而导致到达顺序与发送顺序不一致。因此通常会给数据添加编号,进行编号排序,应用程序接收到数据后重新编排。
- 缓冲区大小有限:接收缓冲区的大小是有限的。当缓冲区满时,新到达的UDP数据报会被丢弃,并且不会通知发送方。因此,如果应用程序不能及时读取数据,就会导致丢包。
全双工
在UDP通信中,通信双方进程在同一时刻,既可以发送数据,也可以接收数据,且互不影响,我们称之为全双工。
- 发送数据时,数据直接封装后交给网络层
- 接收数据时,数据放入接收缓冲区
- 两者互不影响
4.基于UDP的应用层协议
- NFS:网络文件系统
- TFTP:简单文件传输协议
- DHCP:动态主机配置协议
- BOOTP:启动协议(用于无盘设备启动)
- DNS:域名解析协议
当然, 也包括你自己写UDP程序时自定义的应用层协议
5. UDP应用场景
UDP是一种数据量小,数据传输快,传输成本低的协议。通常使用在直播,游戏数据实时传输这类可以允许少量数据损失,对速度要求快的场景
更多推荐




所有评论(0)