《Linux网络编程》6.UDP原理

💡Yupureki:个人主页

✨个人专栏:《C++》 《算法》《Linux系统编程》《高并发内存池》《MySQL数据库》

《个人在线OJ平台》《Linux网络编程》《CMake自动化构建工具》《Redis数据库》


🌸Yupureki🌸的简介:


目录

[1. UDP报头格式](#1. UDP报头格式)

[2. UDP的特点](#2. UDP的特点)

[3. UDP缓冲区](#3. UDP缓冲区)


1. UDP报头格式

UDP 的头部结构固定,没有 TCP 那些复杂的选项字段:

  • 源端口:发送进程绑定的端口,用于回复。可为 0(表示不需要回复)。

  • 目的端口:接收进程的端口,是 UDP 实现多路分用的唯一核心依据。

  • 长度:整个 UDP 数据报的长度(头部+数据),最小为 8(即无数据)。

  • 校验和:覆盖 UDP 头部、数据和从 IP 层提取的部分信息(伪首部),用于差错检测。在 IPv4 中可选(可全为 0 表示不校验),IPv6 中则强制计算。

2. UDP的特点

1. 无连接

发送方在发送数据之前,不需要与接收方建立端到端的连接。每次通信都是独立的。

2. 不可靠传输

这是 UDP 最著名的特点,意味着它将网络本身的"尽力而为"特性直接暴露给应用。

  • 不保证送达:没有确认和重传机制。如果数据报在网络中因拥塞、错误或超时被丢弃,发送方不会得到通知,数据将永久丢失。

  • 不保证顺序:每个数据报独立路由,后发的可能先到达。接收方收到的顺序可能与发送顺序完全不同。

  • 不保证不重复:在极端情况下(如路由环路),一份数据报可能在网络中被复制,接收方可能会收到多份相同报文。

3.面向数据报

UDP 忠实保留了应用层报文的边界,这是它与 TCP 字节流模型的根本区别。

  • 一次发送,一次完整接收 :发送方调用一次 sendto,发送的是一个完整的消息。接收方调用一次 recvfrom,拿到的也一定是这同一个完整消息(假设缓冲区足够)。绝不会出现TCP中常见的"粘包"或"半包"现象。

  • IP 分片依赖:这种"整报交付"的代价是,UDP 自身不对大数据块做分段。如果整个数据报超过路径 MTU,就会强依赖 IP 层分片。任何一个 IP 分片丢失,整个 UDP 数据报就会被丢弃,这大大增加了大报文的丢包风险。

4.支持广播与多播

这是 UDP 独有的能力,TCP 完全无法做到。通过一个 sendto 调用,就能将数据报发给局域网内所有主机(广播)或某个特定组播组的所有成员。这在大规模服务发现、IPTV 直播等场景中不可替代。

UDP 所有特点的本质是 "传输层功能的极端简化",它把数据传输的可靠性、顺序、拥塞管理全盘转嫁给了应用开发者。

因此,UDP 很适合:

  • 需要极低时延且能容忍少量丢包的通信:在线游戏、VoIP、视频会议

  • 需要灵活控制发送节奏或自定义可靠机制的:QUIC / HTTP/3、自定义长连接协议

  • 请求-响应模型简单、数据量小的:DNS、NTP、SNMP

  • 需要一对多数据分发的:直播推流、局域网组播服务、IoT 设备发现

UDP 不适合:

  • 要求数据完整、准确、有序传输且不愿自行实现可靠机制的:文件传输、邮件、网页(这些默认由 TCP 承载)。

3. UDP缓冲区

与 TCP 那种"字节流缓存"不同,UDP 的缓冲区完全是另一套逻辑,直接体现了它无连接、不可靠的本质。

UDP无发送缓冲区,只有接收缓冲区

UDP 的发送侧没有 真正存储待确认数据的缓冲区(不重传)。每调用一次 sendto,内核就立刻将数据封装、下交 IP 层。

那通过 SO_SNDBUF 设置的"发送缓冲区"是什么?它本质上是一个限制单套接字在"发送途中"占用内核内存总量的配额

  • 作用机制:当数据报提交给 IP 层到网卡硬件真正完成发送之间,会短暂占用内核内存(如排队在流量控制 qdisc 中)。如果应用发得过快,占用内存会持续增长。一旦"在途"内存总量超过该配额:

    • 阻塞套接字sendto 会阻塞,直到内存释放。

    • 非阻塞套接字 :立即返回 EAGAIN / EWOULDBLOCK 错误。

  • 实质:它为无节制的 UDP 发送提供了一个本地的"背压"机制,防止一个进程耗尽所有内核内存。

相关推荐
NamoAmitabha12844 分钟前
libpng12-0 1.2.54-1ubuntu1.1 (amd64 binary) in ubuntu xenial
linux·ubuntu20.4
IPdodo_1 小时前
跨境 API 调用不稳定怎么办:出口、超时重试与链路监控的实践
网络·python·网络协议
Madison-No71 小时前
搭建项目测试环境
linux·运维·服务器·python
吴声子夜歌2 小时前
Shell编程实例——编写安全的shell脚本(二)
linux·运维·shell
悠悠121383 小时前
微服务通信别只看性能:REST 与 gRPC 的 6 个选型判断和一次 502 故障复盘
运维·服务器
xiaoye-duck4 小时前
《Linux 网络编程》深入理解 IP 协议(二):网段划分、私有 IP 与 NAT 地址转换
linux·网络·ip
云老大-阿里云国际站代理商4 小时前
华为云国际站服务代理商:NAT网关怎么配?多台ECS共用公网IP要注意什么
服务器·华为云·云计算
zx_741484815 小时前
【Linux入门】Shell 函数、正则表达式与文本处理:cut 与 awk
linux·运维·正则表达式
Zenova EdgeOS5 小时前
Linux dmesg 工业边缘实战:内核日志过滤、持久化与故障定位
linux·运维·边缘计算·工业边缘·dmesg·内核日志
金士顿5 小时前
System.Text.Json Source Generator 深度解析:为什么 Native AOT 不喜欢反射
linux·asp.net core·arm64·net·native aot