第 13.4 節
UDP通信
0瀏覽次數0訪問次數--跳出率--平均停留
Linux UDP 通信
UDP 通信是 Linux 网络编程中非常常见的一种通信方式。
相比 TCP,UDP 不需要提前建立连接,发送方可以直接向指定 IP 和端口发送数据。它的特点是简单、延迟低、开销小,但不保证数据一定送达,也不保证顺序。
在机器人项目中,UDP 常用于高频、实时、允许少量丢包的数据传输场景。
在实际项目中,UDP 通信常见于:
- 激光雷达数据传输
- 网络相机或传感器数据流
- 机器人状态广播
- 局域网设备发现
- 遥控器或手柄数据传输
- 多机器人之间的简单通信
- 高频状态上报
- 对实时性要求高、但允许少量丢包的场景
UDP 的核心特点是快,但不可靠。因此它更适合“持续发送的数据流”,而不是“必须保证每条消息都送达”的场景。
UDP 通信是什么
UDP,全称 User Datagram Protocol,是一种无连接的传输协议。
和 TCP 不同,UDP 通信不需要建立连接。只要知道目标 IP 和端口,就可以直接发送数据。
典型结构如下:
UDP Sender
↓
UDP Receiver
也可以是双向通信:
程序 A ←UDP→ 程序 B
常见概念包括:
| 概念 | 说明 |
|---|---|
| IP 地址 | 用来定位网络中的设备 |
| 端口号 | 用来区分不同程序 |
| Datagram | UDP 数据报,一次发送对应一个数据报 |
| 广播 | 向局域网内多个设备发送数据 |
| 组播 | 向加入同一组播组的设备发送数据 |
| 丢包 | UDP 不保证数据一定送达 |
| 乱序 | UDP 不保证数据按顺序到达 |
UDP 和 TCP 最大的区别是:TCP 是可靠字节流,UDP 是不可靠数据报。
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 数据报的发送和接收,只是封装方式不同。
各方案对比
| 方案 | 优点 | 缺点 |
|---|---|---|
| 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 学习 |
本教程建议选择
本教程建议优先选择:
boost::asio
原因是:
- 适合 C++ 工程开发
- 和 TCP、串口、定时器可以使用同一套 Boost.Asio 编程模型
- 支持同步和异步 UDP 收发
- 不依赖 ROS 2,方便在普通 C++、OpenCV、Qt、嵌入式 Linux 项目中复用
- 适合封装网络传感器、远程遥控、状态广播等功能
推荐的工程结构是:
上层项目:ROS 2 / OpenCV / Qt / 普通 C++ 程序
↓
自己封装的 UdpSender / UdpReceiver 类
↓
boost::asio
↓
UDP socket
↓
雷达 / 网络设备 / 远程控制端
TCP 和 UDP 怎么选
TCP 和 UDP 都很常用,但适合的场景不同。
| 对比项 | TCP | UDP |
|---|---|---|
| 是否连接 | 需要建立连接 | 不需要建立连接 |
| 可靠性 | 可靠传输 | 不保证送达 |
| 顺序 | 保证顺序 | 不保证顺序 |
| 延迟 | 相对更高 | 相对更低 |
| 适合数据 | 命令、配置、文件、日志 | 高频数据、广播、实时状态 |
| 典型场景 | 远程控制、服务器通信、参数配置 | 雷达数据、遥控数据、状态广播 |
简单理解:
TCP:我要确保这条消息送到
UDP:我要快速持续发送,偶尔丢一包也能接受
与 ROS 2 的关系
学习 UDP,并不代表要用 UDP 替代 ROS 2 的 topic。
在 ROS 2 系统内部,节点之间通信通常优先使用 ROS 2 自己的通信机制。而 UDP 更适合用来连接 ROS 2 系统之外的网络设备,或者实现轻量级的远程通信。
例如:
激光雷达
↓
UDP 数据包
↓
自己封装的 UdpReceiver
↓
ROS 2 节点发布点云 / LaserScan
也可以用于:
远程遥控端
↓
UDP
↓
机器人主控程序
本章学习目标
学习完本章后,应该能够掌握:
- UDP 通信的基本概念
- UDP 和 TCP 的主要区别
- IP 地址、端口号、endpoint 的含义
- 使用 C++ 发送和接收 UDP 数据
- 理解 UDP 丢包、乱序、广播等特性
- 使用 Boost.Asio 封装 UDP 通信类
- 为后续雷达数据接收、远程遥控、状态广播打基础