如何在通过wsServer发送的JPEG数据前添加Unix时间戳
在C中拼接Unix时间戳与JPEG数据发送WebSocket二进制帧
核心实现步骤
要构建<timestamp><jpeg_data>的二进制消息格式,需要完成以下操作:
- 统一字节序(推荐大端序,保证跨平台解析一致性)
- 分配足够内存存储时间戳+JPEG数据
- 将
unsigned long long类型时间戳转为字节序列 - 拼接JPEG数据到时间戳字节后
- 发送数据并释放内存避免泄漏
修改后的完整代码
#include <stdlib.h> #include <string.h> #include <arpa/inet.h> // 用于系统自带的htonll(若支持) // 若系统未提供htonll,手动实现大端转换函数 static uint64_t htonll(uint64_t val) { #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ return ((uint64_t)htonl(val) << 32) | htonl(val >> 32); #else return val; #endif } static void send_frame(gpointer addr, gpointer client, gpointer provider) { ImgProvider_t* p = provider; Watcher* c = client; const size_t timestamp_len = sizeof(uint64_t); // unsigned long long固定为8字节 const size_t jpeg_len = vdo_frame_get_size(p->frame); const size_t total_len = timestamp_len + jpeg_len; // 分配内存存储拼接后的数据 uint8_t* combined_buf = malloc(total_len); if (!combined_buf) { // 内存分配失败的容错处理,比如打印日志 return; } // 将时间戳转为大端字节序,写入内存头部 uint64_t timestamp_be = htonll(p->timestamp); memcpy(combined_buf, ×tamp_be, timestamp_len); // 拷贝JPEG数据到时间戳之后的位置 memcpy(combined_buf + timestamp_len, p->buffer_data, jpeg_len); // 发送拼接好的二进制帧 ws_sendframe_bin(c->connection, combined_buf, total_len); // 释放内存,避免泄漏 free(combined_buf); }
关键细节说明
- 字节序兼容:
htonll将主机字节序转为网络大端序,JS端解析时需对应使用大端读取,避免不同CPU架构的解析错误。 - 内存管理:
malloc分配的内存必须用free释放,否则会持续占用内存导致泄漏。 - JS端解析示例:收到二进制消息后可这样提取时间戳和JPEG数据:
// 假设msg是收到的ArrayBuffer const timestampView = new DataView(msg, 0, 8); const timestamp = timestampView.getBigUint64(0, false); // false指定大端序 const jpegData = msg.slice(8); // 截取从第8字节开始的JPEG数据
内容的提问来源于stack exchange,提问作者Christoph
相关产品推荐
相关产品推荐

