一、MQTT 是什么核心架构MQTT 是发布/订阅模式物联网通信协议架构只有 3 部分Broker MQTT 服务端中转站mosquitto 程序只负责转发消息不处理业务MQTT 客户端你的 C 程序subscribe(主题)订阅 →接收别人发给这个主题的消息publish(主题,内容)发布 →向这个主题广播消息通信方式长连接 TCP通信流程任意客户端发布消息 → Broker 收到 → 转发给所有订阅该主题的客户端客户端互相不知道对方IP只靠主题Topic通信二、Linux 搭建本地 MQTT 服务端 Mosquitto1. 安装服务端 命令行测试工具sudoaptupdatesudoaptinstallmosquitto mosquitto-clients2. 启动服务 开机自启# 启动MQTT服务sudosystemctl start mosquitto# 设置开机自动运行sudosystemctlenablemosquitto3. 查看服务运行状态sudosystemctl status mosquitto出现active (running)代表服务正常默认地址localhost默认端口1883默认无账号密码直接连接4. 命令行原生测试验证服务是否正常终端1订阅主题等待收消息mosquitto_sub-ttest/topic终端2发布消息发送消息mosquitto_pub-ttest/topic-mHello MQTT终端1立刻收到消息 → 服务端完全正常三、安装 C MQTT 客户端库 libmosquittosudoaptinstalllibmosquitto-dev四、C MqttClient 完整流程逐行详解1. 构造函数做了什么MqttClient::MqttClient(...){// 1. 初始化mosquitto库mosquitto_lib_init();// 2. 创建客户端实例// 参数1客户端ID// 参数2是否清理旧会话// 参数3this → 当前client对象地址回调要用mosq_mosquitto_new(client_id.c_str(),true,this);}这里传入的this main 里MqttClient client(...)这个对象本身的地址2. 注册三个核心回调重中之重// 1. 连接结果回调连接成功/失败后自动调用mosquitto_connect_callback_set(mosq_,on_connect_callback);// 2. 消息接收回调订阅主题收到消息自动调用mosquitto_message_callback_set(mosq_,on_message_callback);// 3. 断开连接回调掉线/主动断开自动调用mosquitto_disconnect_callback_set(mosq_,on_disconnect_callback);3. 回调函数参数完整解释① 连接回调 on_connect_callbackvoidon_connect_callback(structmosquitto*,void*obj,intresult)第1参数库内部客户端对象不用管第2参数obj就是你传的this强转得到C对象第3参数result连接状态0 连接成功非0 连接失败执行mosquitto_connect()连接完成后立刻触发此回调② 消息回调 on_message_callbackvoidon_message_callback(structmosquitto*,void*obj,conststructmosquitto_message*msg)第1参数库内部对象第2参数objC对象指针第3参数msg消息结构体msg-topic消息主题msg-payload消息数据指针地址msg-payloadlen消息长度判断逻辑必须if(payload!nullptrpayloadlen0)先判断指针不为空防止空指针崩溃再判断长度③ 断开回调 on_disconnect_callbackvoidon_disconnect_callback(structmosquitto*,void*obj,intrc)rc0主动正常断开rc≠0网络异常、掉线、服务端断开4. 连接 Brokerintrcmosquitto_connect(mosq_,主机,端口,keepalive_);keepalive 心跳详解60秒不是连接超时不是连不上就退出含义60秒内没有任何业务消息收发libmosquitto自动发送PING心跳包你不用写任何代码TCP静默断线检测不到靠心跳证明客户端存活超过2倍时长无心跳Broker判定设备离线断开连接你不publish、不收消息完全不影响心跳正常运行5. 订阅主题client.subscribe(test/topic,1);告诉Broker这个主题的所有消息都转发给我6. 发布消息client.publish(test/topic,内容,0,false);向主题广播消息所有订阅该主题客户端都会收到7. 消息循环 loop()voidMqttClient::loop(){while(true){mosquitto_loop(mosq_,-1,1);// 处理收发消息、心跳、重连}}无限循环阻塞持续监听网络事件物联网设备本来就需要一直运行不退出主线程用线程跑loop不卡住其他业务按CtrlC优雅退出8. 析构函数释放资源~MqttClient(){mosquitto_disconnect(mosq_);// 断开连接mosquitto_destroy(mosq_);// 销毁客户端mosquitto_lib_cleanup();// 清理库资源}五、C程序编译 运行完整命令1. 编译g mqtt_client.cpp-omqtt_client-lmosquitto-pthread2. 运行连接本地MQTT服务端./mqtt_client localhost1883六、完整双向测试流程必做方式1C ↔ 命令行互相通信运行你的C程序订阅test/topic新开终端发布消息mosquitto_pub-ttest/topic-m终端发来消息C程序立刻回调打印收到内容方式2两个C客户端互相聊天终端A运行C订阅test/topic终端B运行C发布消息终端A自动收到七、常见问题汇总Connection refusedmosquitto 服务没启动执行sudo systemctl start mosquitto程序一直不退出loop是无限死循环物联网常驻程序本来就这样正常收不到消息主题名字大小写、符号必须完全一模一样长时间没发消息会不会掉线不会库自动心跳保活八、极简整体流程总结安装启动Mosquitto服务端C创建MqttClient对象注册连接、消息、断开三个回调设置60秒keepalive心跳连接Broker订阅主题等待收消息发布消息发送数据loop循环持续监听CtrlC正常退出程序退出自动释放所有MQTT资源