MQTT-C 快速上手:两千行 C 代码的 MQTT 客户端,一小时跑通传感器上报
【免费下载链接】MQTT-CA portable MQTT C client for embedded systems and PCs alike.项目地址: https://gitcode.com/gh_mirrors/mq/MQTT-C
周末晚上,我盯着桌上那块闲置的 STM32 开发板。温湿度传感器每五秒吐一个数据,我想把它发到树莓派上的 MQTT broker,让手机随时看到客厅温度——此刻我需要的正是一个轻量级 MQTT C 客户端。而 MQTT-C,就是我在那一刻遇到的答案。
一块开发板和一个想省事的晚上
我一开始选了个功能很全的 MQTT 库。交叉编译、依赖配置、内存裁剪……光是让它在我那块小板上编译通过,就用掉了一整晚。可我的需求明明很简单:连上 broker、定时发一条消息、偶尔收一条下发的指令。为一个发布动作付出这么多代价,不值。
后来同事甩给我一个仓库,说"试试这个,只有两个文件"。我半信半疑地打开——确实只有两个源文件。这就是 MQTT-C。🌡️
它是谁:一个不添乱的 C 语言 MQTT 客户端
MQTT-C 是一个用纯 C 实现的 MQTT v3.1.1 客户端,定位很明确:为嵌入式系统和普通 PC 提供可移植的 MQTT 通信能力。它最大的特点是"不添乱":
- 够小:核心代码只有
src/mqtt.c和src/mqtt_pal.c两个文件,加起来不到 2000 行 - 够透明:平台抽象层(PAL)把 socket、时间、锁这些系统依赖全部隔离,换平台只改一个文件
- 够灵活:所有 API 线程安全,但单线程裸机环境也能正常跑
不偷偷 malloc、不悄悄起线程、不强制任何框架——这些"不做的事",恰恰是嵌入式开发者最看重的品质。
第一次上手:从 clone 到收到第一条消息
拿到代码很简单:
git clone https://gitcode.com/gh_mirrors/mq/MQTT-C编译更简单。库本身不依赖第三方,直接和你的源码一起编就行:
gcc -o my_app my_app.c src/mqtt.c src/mqtt_pal.c -Iinclude接着是初始化和连接。下面这段代码做了两件事:把客户端绑定到已打开的 socket 上,然后向 broker 发起连接请求。
struct mqtt_client client; uint8_t sendbuf[2048], recvbuf[1024]; mqtt_init(&client, sockfd, sendbuf, sizeof(sendbuf), recvbuf, sizeof(recvbuf), publish_callback); mqtt_connect(&client, "dev01", NULL, NULL, 0, NULL, NULL, MQTT_CONNECT_CLEAN_SESSION, 400);注意 sendbuf 和 recvbuf 是你自己提供的缓冲区,库全程不自己分配内存——内存用在哪、用了多少,你心里有数。这一点,在 RAM 只有几十 KB 的板子上是救命级的设计。
然后,发布一条消息:
mqtt_publish(&client, "home/temperature", "25.5", 4, MQTT_PUBLISH_QOS_0);我第一次跑通时,树莓派上的订阅端打出了25.5。那一刻的成就感,比任何"Hello World"都实在。✅
实际干活:发布、订阅、QoS 和心跳
上手之后,我对照项目里的示例把核心能力挨个试了一遍,每一样都有看得见的效果。
发布与订阅。库实现了完整的发布/订阅模型,订阅一个主题只要一行:
mqtt_subscribe(&client, "home/temperature", 0);之后 broker 推来的每条消息都会进你的回调函数,你在里面解析主题和载荷就行。
三种 QoS 按需选。项目提供 QoS 0、1、2 三档服务质量。我起初一律用 QoS 1,后来发现温度数据丢一两条无所谓,改成 QoS 0 后流量和内存都省了不少。选哪档,取决于"这条消息丢了会怎样"。
心跳与同步。库不会自己收发包,你需要周期性地调用一次mqtt_sync,让它处理进出站流量、维持心跳保活。官方示例里用 100ms 的间隔开一个刷新线程;单线程板子上,把mqtt_sync塞进主循环即可。这种"你来决定何时干活"的设计,让库在任何调度模型里都安分。
断线重连。我一度担心网络抖动。翻到examples/reconnect_subscriber.c发现,注册一个 reconnect 回调,断线时库会自动重新连接并恢复订阅。我故意重启了两次树莓派上的 broker,订阅端都自己回来了,省心。
新手容易踩的坑
几处我亲手踩过的坑,提前写给你:
- 缓冲区别抠门。sendbuf 要能装下多条完整消息,太小会直接报错。我第一次只给了 256 字节,发布稍长的 payload 就翻车。
- 回调里的 topic_name 不是字符串。它没有
\0结尾,直接printf会读到垃圾数据。官方订阅示例里先复制再补结尾,照抄就行。 - 忘了调
mqtt_sync,一切静悄悄。发不出去也收不到,排查半天才发现是刷新循环没跑。 - 想要加密连接?直接看
examples/openssl_publisher.c和examples/mbedtls_publisher.c,别自己在 socket 上裸写 TLS,那是给自己挖坑。💡
它能用在哪儿
我自己的项目是智能家居的温度上报,但它的适用面比这宽得多:
- 嵌入式设备:MCU、RTOS、单线程裸机,换好 PAL 就能跑
- PC 端工具:Linux 上写个状态上报的小服务,几行代码的事
- 工业场景:设备状态、告警、遥测数据的低延迟上报
- 加密方案:OpenSSL、mbedTLS、BearSSL 三种示例齐全,按平台选
项目还自带基于 cmocka 的单元测试(tests.c),make all能一键编译全部示例和测试,再跑一遍./bin/tests就能验证你的移植是否正常——这在嵌入式库里算很贴心了。
什么时候该选它
回到开头那块开发板。第二天晚上,它已经把客厅温度乖乖上报到树莓派,手机 App 曲线平滑,我再没为通信这件事操过心。🎉
如果你也在 C 工程里需要 MQTT,尤其是要跑在资源受限的硬件上,或者你只是想要一个代码量小、内存可控、行为透明的客户端——MQTT-C 值得你花一个小时试试。从 clone 到第一条消息,我保证比你想象中快。
【免费下载链接】MQTT-CA portable MQTT C client for embedded systems and PCs alike.项目地址: https://gitcode.com/gh_mirrors/mq/MQTT-C
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考