-
Notifications
You must be signed in to change notification settings - Fork 1
NET_DataPacket
SweerItTer edited this page Feb 21, 2026
·
1 revision
DataPacket 是数据包类型,支持多种数据传输方式,包括普通文本、DMA-BUF 零拷贝和裸文件描述符。
struct DataPacket {
enum class PacketType : uint8_t {
TEXT, // 普通文本数据
DMABUF_FD, // DMA-BUF文件描述符
RAW_FD // 裸文件描述符
};
PacketType type;
std::string textData; // type == TEXT时使用
int dmaFd{-1}; // type == DMABUF_FD时使用
DmaBufferPtr dmabufPtr{nullptr}; // type == DMABUF_FD时使用(持有所有权)
int rawFd{-1}; // type == RAW_FD时使用
};描述: 普通文本数据,使用 send() 发送。
适用场景:
- 命令响应
- 配置信息
- 状态查询
- 日志输出
特点:
- 简单易用
- 自动序列化
- 支持任意字符串
描述: DMA-BUF 文件描述符,使用 sendmsg() + SCM_RIGHTS 发送,实现零拷贝传输。
适用场景:
- 视频帧传输
- 图像数据传输
- 大数据块传输
- 多媒体应用
特点:
- 零拷贝,性能高
- 需要 DRM 支持
- 自动管理生命周期
- 跨进程共享
描述: 裸文件描述符,使用 sendmsg() + SCM_RIGHTS 发送。
适用场景:
- 共享文件描述符
- 管道传输
- Socket 转发
- 资源共享
特点:
- 灵活通用
- 支持任意 FD
- 手动管理生命周期
签名:
static DataPacket createText(const std::string& data)描述: 创建文本数据包。
参数:
-
data: 文本数据
返回值: DataPacket 对象
示例:
DataPacket pkt = DataPacket::createText("Hello World");
server.sendToClient(clientId, pkt);使用场景:
- 命令响应
- 状态信息
- 配置数据
- 普通消息
签名:
static DataPacket createDmaBuf(DmaBufferPtr dmabuf)描述: 创建 DMA-BUF 数据包(零拷贝)。
参数:
-
dmabuf: DMA-BUF 指针
返回值: DataPacket 对象
示例:
// 创建 DMA-BUF
DmaBufferPtr dmabuf = DmaBuffer::create(1920, 1080, DRM_FORMAT_ARGB8888);
// 填充数据
memset(dmabuf->map(), 0xFF, dmabuf->size());
// 创建数据包
DataPacket pkt = DataPacket::createDmaBuf(dmabuf);
server.sendToClient(clientId, pkt);使用场景:
- 视频帧传输
- 图像数据传输
- 大数据块传输
- 多媒体应用
注意事项:
- 需要 DRM 支持
- 自动管理生命周期
- 零拷贝传输,性能高
签名:
static DataPacket createRawFd(int fd)描述: 创建裸文件描述符数据包。
参数:
-
fd: 文件描述符
返回值: DataPacket 对象
示例:
// 打开文件
int fd = open("/path/to/file.txt", O_RDONLY);
// 创建数据包
DataPacket pkt = DataPacket::createRawFd(fd);
server.sendToClient(clientId, pkt);
// 注意:fd 会在发送后被关闭使用场景:
- 共享文件描述符
- 管道传输
- Socket 转发
- 资源共享
注意事项:
- FD 会在发送后被关闭
- 确保接收端正确处理
- 手动管理生命周期
// 命令响应
DataPacket pkt = DataPacket::createText("OK File received");
server.sendToClient(clientId, pkt);
// 状态信息
DataPacket status = DataPacket::createText("Server is running");
server.broadcast(status);
// 配置数据
DataPacket config = DataPacket::createText("PORT=8080,MAX_CLIENTS=64");
server.sendToClient(clientId, config);// 创建 DMA-BUF
DmaBufferPtr dmabuf = DmaBuffer::create(1920, 1080, DRM_FORMAT_ARGB8888);
// 填充数据(视频帧)
uint32_t* pixels = static_cast<uint32_t*>(dmabuf->map());
for (int i = 0; i < 1920 * 1080; ++i) {
pixels[i] = 0xFF0000; // 红色
}
// 创建数据包
DataPacket pkt = DataPacket::createDmaBuf(dmabuf);
// 发送给客户端(零拷贝)
server.sendToClient(clientId, pkt);// 打开文件
int fd = open("/path/to/large_file.dat", O_RDONLY);
if (fd < 0) {
// 发送错误
server.sendToClient(clientId, DataPacket::createText("ERROR Cannot open file"));
return;
}
// 创建数据包
DataPacket pkt = DataPacket::createRawFd(fd);
// 发送给客户端
server.sendToClient(clientId, pkt);
// 注意:fd 会在发送后被自动关闭// 广播文本消息
DataPacket broadcastMsg = DataPacket::createText("Server will restart in 5 minutes");
size_t sent = server.broadcast(broadcastMsg);
std::cout << "Broadcast to " << sent << " clients" << std::endl;
// 广播视频帧(多个客户端)
DmaBufferPtr frame = captureVideoFrame();
DataPacket pkt = DataPacket::createDmaBuf(frame);
size_t sent = server.broadcast(pkt);创建 DataPacket (type = TEXT)
├─ 设置 textData
└─ 发送队列
└─ send()
├─ 序列化
└─ 发送到 socket
创建 DataPacket (type = DMABUF_FD)
├─ 保存 dmabufPtr (持有所有权)
└─ 发送队列
└─ sendmsg() + SCM_RIGHTS
├─ 提取 fd (dmabuf->fd())
├─ 构建 msghdr
└─ 发送(零拷贝)
创建 DataPacket (type = RAW_FD)
├─ 保存 rawFd
└─ 发送队列
└─ sendmsg() + SCM_RIGHTS
├─ 构建 msghdr
└─ 发送
| 类型 | 拷贝次数 | 性能 | 适用场景 |
|---|---|---|---|
| TEXT | 2次 | 中等 | 命令响应、配置 |
| DMABUF_FD | 0次 | 最高 | 视频帧、大数据 |
| RAW_FD | 0次 | 高 | 文件共享、管道 |
拷贝次数说明:
- TEXT: 内存 → 内核 → 网络(2次)
- DMABUF_FD: 直接传输(0次)
- RAW_FD: 直接传输(0次)
DataPacket pkt = DataPacket::createText("Hello");
if (!server.sendToClient(clientId, pkt)) {
// 发送失败
std::cerr << "Send failed" << std::endl;
}DmaBufferPtr dmabuf = DmaBuffer::create(1920, 1080, DRM_FORMAT_ARGB8888);
if (!dmabuf) {
// DMA-BUF 创建失败
server.sendToClient(clientId, DataPacket::createText("ERROR Cannot create DMA-BUF"));
return;
}int fd = open("/path/to/file.txt", O_RDONLY);
if (fd < 0) {
// FD 无效
server.sendToClient(clientId, DataPacket::createText("ERROR Cannot open file"));
return;
}-
选择合适的类型:
- 普通数据使用 TEXT
- 视频/大块数据使用 DMABUF_FD
- 文件共享使用 RAW_FD
-
生命周期管理:
- DMABUF_FD: 自动管理,无需手动释放
- RAW_FD: 发送后自动关闭
- TEXT: 无生命周期问题
-
性能优化:
- 大数据使用零拷贝
- 批量发送使用队列
- 避免频繁创建/销毁
-
错误处理:
- 检查发送结果
- 验证 FD 有效性
- 捕获异常
- TcpServer - TCP 服务器
- SocketConnection - Socket 连接
- CommandHandler - 命令处理器
- DmaBuffer - DMA 缓冲区
主页
API 文档
DMA 模块
DRM 模块
- DRM 模块总览
- DeviceController - DRM 设备控制器
- DrmLayer - DRM 图层管理
- PlanesCompositor - DRM 平面合成器
- DrmBpp - DRM 格式定义
NET 模块
- NET 模块总览
- TcpServer - TCP 服务器
- SocketConnection - Socket 连接管理
- CommandHandler - 命令处理器
- DataPacket - 数据包
V4L2 模块
- V4L2 模块总览
- CameraController - V4L2 摄像头控制器
- Frame - V4L2 帧数据结构
- FormatTool - V4L2 格式工具
- Exception - V4L2 异常类
V4L2Param 模块
- V4L2Param 模块总览
- ParamControl - 参数控制
- ParamLogger - 参数日志
- ParamProcessor - 参数处理器
RGA 模块
- RGA 模块总览
- RgaConverter - RGA 转换器
- RgaProcessor - RGA 处理器
- FormatTool - RGA 格式工具
MPP 模块
- MPP 模块总览
- EncoderContext - 编码器上下文
- EncoderCore - 编码器核心
- JpegEncoder - JPEG 编码器
- StreamWriter - 流写入器
- MppResourceGuard - MPP 资源守护
- FileTools - 文件工具
- FormatTool - 格式工具
Sys 模块
- Sys 模块总览
- CpuMonitor - CPU 监控器
- MemoryMonitor - 内存监控器
- Base - 基础类
Mouse 模块
- Mouse 模块总览
- Watcher - 鼠标监视器
Utils 模块
- Utils 模块总览
- AsyncThreadPool - 异步线程池
- ConcurrentQueue - 并发队列
- FdWrapper - 文件描述符包装器
- FenceWatcher - 围栏监视器
- FixedSizePool - 固定大小对象池
- Logger - 日志记录器
- ObjectsPool - 对象池
- OrderedQueue - 有序队列
- ProgressBar - 进度条
- SafeQueue - 安全队列
- SharedBufferState - 共享缓冲区状态
- SimpleVariant - 简单变体类型
- ThreadPauser - 线程暂停器
- ThreadUtils - 线程工具
- Types - 类型定义
- UdevMonitor - Udev 监视器