Mosquitto C中如何正确发送与接收结构体作为消息负载?
结构体作为MQTT消息负载的正确实现(C语言+libmosquitto)
原代码的核心问题
- 发布端参数错误:
mosquitto_publish的payload参数要求是void*类型,直接传入结构体变量defaults会导致类型不匹配,需传递结构体地址&defaults。 - 未初始化的垃圾数据:发布的结构体包含未赋值的
uid数组,栈上的随机垃圾数据会被一并发送,可能引发接收端解析异常。 - 接收端内存复制错误:使用
memset完全错误——该函数是用指定字节值填充内存,而非复制内存块,正确操作是用memcpy。 - 潜在跨平台对齐问题:默认结构体对齐规则可能导致不同平台上结构体大小、字段偏移不一致,跨设备传输时会出现解析错位。
修正后的完整实现
1. 定义带对齐控制的结构体
添加对齐指令,确保不同平台上结构体内存布局一致:
#pragma pack(push, 1) // 强制1字节对齐,消除平台差异 typedef struct { char uid[100]; unsigned int ka; unsigned int interval; } Config; #pragma pack(pop)
2. 发布端代码
// 初始化结构体,清空所有字段避免垃圾数据 Config defaults; memset(&defaults, 0, sizeof(defaults)); // 填充需要发送的字段 defaults.ka = 60; defaults.interval = 45; // 调用mosquitto_publish,传递结构体地址作为payload int ret = mosquitto_publish( mosq, NULL, "topic", sizeof(defaults), &defaults, // 此处必须传入指针 2, true ); if (ret != MOSQ_ERR_SUCCESS) { syslog(LOG_ERR, "发布失败: %s", mosquitto_strerror(ret)); }
3. 接收端代码
syslog(LOG_INFO, "收到默认配置!"); // 先检查payload长度是否匹配结构体大小,避免内存越界 if (msg->payloadlen != sizeof(Config)) { syslog(LOG_WARNING, "配置消息长度不匹配,丢弃"); return; } Config default_config; // 用memcpy复制payload到结构体 memcpy(&default_config, msg->payload, sizeof(default_config)); // 处理配置 handleDefaultConfigAcquisition(&default_config);
额外注意事项
- 若无需发送
uid字段,建议单独定义用于传输的结构体(如ConfigPayload),仅包含ka和interval,减少传输数据量并避免不必要字段干扰。 - 始终检查
mosquitto_publish的返回值,及时处理发布失败场景。 - 接收端必须验证消息长度,防止恶意或错误消息导致内存越界。
内容的提问来源于stack exchange,提问作者Sans the Medic
相关产品推荐
相关产品推荐

