Wiki
UDP通信
An English translation is not available yet. The latest Simplified Chinese source is shown without triggering paid translation.
1.Linux UDP 通信
UDP 通信是 Linux 网络编程中非常常见的一种通信方式。
相比 TCP,UDP 不需要提前建立连接,发送方可以直接向指定 IP 和端口发送数据。它的特点是简单、延迟低、开销小,但不保证数据一定送达,也不保证顺序。
在机器人项目中,UDP 常用于高频、实时、允许少量丢包的数据传输场景。
在实际项目中,UDP 通信常见于:
- 激光雷达数据传输
- 网络相机或传感器数据流
- 机器人状态广播
- 局域网设备发现
- 遥控器或手柄数据传输
- 多机器人之间的简单通信
- 高频状态上报
- 对实时性要求高、但允许少量丢包的场景
UDP 的核心特点是快,但不可靠。因此它更适合“持续发送的数据流”,而不是“必须保证每条消息都送达”的场景。
1.1.UDP 通信是什么
UDP,全称 User Datagram Protocol,是一种无连接的传输协议。
和 TCP 不同,UDP 通信不需要建立连接。只要知道目标 IP 和端口,就可以直接发送数据。
典型结构如下:
UDP Sender
↓
UDP Receiver
也可以是双向通信:
程序 A ←UDP→ 程序 B
常见概念包括:
| 概念 | 说明 |
|---|---|
| IP 地址 | 用来定位网络中的设备 |
| 端口号 | 用来区分不同程序 |
| Datagram | UDP 数据报,一次发送对应一个数据报 |
| 广播 | 向局域网内多个设备发送数据 |
| 组播 | 向加入同一组播组的设备发送数据 |
| 丢包 | UDP 不保证数据一定送达 |
| 乱序 | UDP 不保证数据按顺序到达 |
UDP 和 TCP 最大的区别是:TCP 是可靠字节流,UDP 是不可靠数据报。
1.2.Linux 下常见 UDP 库
Linux 下进行 UDP 通信有多种方案,常见的包括:
| 方案 | 类型 | 特点 | 适合场景 |
|---|---|---|---|
| Linux socket API | Linux 原生接口 | 最底层、依赖少、通用性强 | 想深入理解网络通信机制 |
| boost::asio | 通用 C++ 网络库 | 支持同步/异步 UDP,适合工程封装 | 推荐用于 C++ 项目 |
| Qt Network | Qt 网络模块 | 和 Qt 界面程序结合方便 | Qt 上位机 |
| Python socket | Python 标准库 | 简单方便,适合测试 | Python 调试脚本 |
| ROS 2 topic | ROS 2 通信机制 | ROS 2 内部通信方便 | ROS 2 系统内部数据传输 |
这些方案本质上都是为了完成 UDP 数据报的发送和接收,只是封装方式不同。
1.3.各方案对比
| 方案 | 优点 | 缺点 |
|---|---|---|
| Linux socket API | 原生、稳定、依赖少、通用性强 | 代码相对繁琐,异步处理麻烦 |
| boost::asio | C++ 工程友好,异步 UDP 方便,适合封装 driver | 需要理解 io_context、endpoint、socket 等概念 |
| Qt Network | 和 Qt 程序结合自然,适合上位机 | 不适合脱离 Qt 的底层 driver |
| Python socket | 上手快,适合测试 UDP 包 | 不适合作为 C++ 底层主线 |
| ROS 2 topic | ROS 2 内部通信方便 | 不适合替代通用 UDP 学习 |
1.4.本教程建议选择
本教程建议优先选择:
boost::asio
原因是:
- 适合 C++ 工程开发
- 和 TCP、串口、定时器可以使用同一套 Boost.Asio 编程模型
- 支持同步和异步 UDP 收发
- 不依赖 ROS 2,方便在普通 C++、OpenCV、Qt、嵌入式 Linux 项目中复用
- 适合封装网络传感器、远程遥控、状态广播等功能
推荐的工程结构是:
上层项目:ROS 2 / OpenCV / Qt / 普通 C++ 程序
↓
自己封装的 UdpSender / UdpReceiver 类
↓
boost::asio
↓
UDP socket
↓
雷达 / 网络设备 / 远程控制端
1.5.TCP 和 UDP 怎么选
TCP 和 UDP 都很常用,但适合的场景不同。
| 对比项 | TCP | UDP |
|---|---|---|
| 是否连接 | 需要建立连接 | 不需要建立连接 |
| 可靠性 | 可靠传输 | 不保证送达 |
| 顺序 | 保证顺序 | 不保证顺序 |
| 延迟 | 相对更高 | 相对更低 |
| 适合数据 | 命令、配置、文件、日志 | 高频数据、广播、实时状态 |
| 典型场景 | 远程控制、服务器通信、参数配置 | 雷达数据、遥控数据、状态广播 |
简单理解:
TCP:我要确保这条消息送到
UDP:我要快速持续发送,偶尔丢一包也能接受
1.6.与 ROS 2 的关系
学习 UDP,并不代表要用 UDP 替代 ROS 2 的 topic。
在 ROS 2 系统内部,节点之间通信通常优先使用 ROS 2 自己的通信机制。而 UDP 更适合用来连接 ROS 2 系统之外的网络设备,或者实现轻量级的远程通信。
例如:
激光雷达
↓
UDP 数据包
↓
自己封装的 UdpReceiver
↓
ROS 2 节点发布点云 / LaserScan
也可以用于:
远程遥控端
↓
UDP
↓
机器人主控程序
1.7.本章学习目标
学习完本章后,应该能够掌握:
- UDP 通信的基本概念
- UDP 和 TCP 的主要区别
- IP 地址、端口号、endpoint 的含义
- 使用 C++ 发送和接收 UDP 数据
- 理解 UDP 丢包、乱序、广播等特性
- 使用 Boost.Asio 封装 UDP 通信类
- 为后续雷达数据接收、远程遥控、状态广播打基础