MQTT通信之paho.mqtt.c、mosquitto库的使用
MQTT 简介
MQTT(Message Queuing Telemetry Transport) 是一种基于发布/订阅模式的轻量级消息传输协议,专为低带宽、高延迟或不稳定的网络环境设计。广泛应用于物联网(IoT)、移动应用、智能家居等领域。
MQTT 的核心作用与功能
- 轻量高效:协议开销小,适合资源受限的设备。
- 发布/订阅模型:
- 发布者(Publisher):发送消息到特定主题(Topic)。
- 订阅者(Subscriber):订阅主题以接收消息。
- 代理服务器(Broker):中转消息,负责主题匹配与消息分发。
- 服务质量(QoS):
- QoS 0:最多一次(可能丢失)。
- QoS 1:至少一次(可能重复)。
- QoS 2:恰好一次(可靠传输)。
- 遗嘱消息(LWT):客户端异常断开时,代理自动发布预设消息。
- 保留消息(Retained):新订阅者立即收到主题的最新消息。
MQTT 通信流程
- 客户端连接代理:
- 订阅主题:
- 消息发布与接收:
- 断开连接:
MQTT 工作原理
- 主题分层:主题以
/分隔,如sensors/temperature/room1。 - 通配符:
+:单层匹配(如sensors/+/room1)。#:多层匹配(如sensors/#)。
- 代理路由:代理根据主题匹配将消息分发给订阅者。
在Ubuntu上下载、编译和使用
在Ubuntu系统中,我们将使用两种库实现MQTT通信:paho_mqtt.c(Eclipse Paho C客户端库)和mosquitto(Mosquitto库)。首先安装代理和依赖:
- 安装依赖
sudo apt update
sudo apt install build-essential cmake libssl-dev
-
安装Mosquitto Broker:
Mosquitto是一个流行的MQTT代理,用于测试。在终端执行:sudo apt update sudo apt install mosquitto mosquitto-clients sudo apt install libmosquitto-dev启动代理:
sudo systemctl start mosquitto验证代理运行:
sudo systemctl status mosquitto。 -
安装 Paho MQTT C 库:
- 通用依赖:
sudo apt install build-essential cmake openssl libssl-dev - paho_mqtt.c库:从源码编译安装。
git clone https://github.com/eclipse/paho.mqtt.c.git cd paho.mqtt.c cmake -B build -DCMAKE_INSTALL_PREFIX=/usr/local cmake --build build sudo cmake --install build
- 通用依赖:
现在,我们可以编写C语言代码实现客户端和服务端通信。服务端在MQTT上下文中通常指订阅者客户端,我们将实现:
- 客户端:发布消息。
- 服务端:订阅消息。
使用两种库分别实现,并添加TLS支持。
使用paho_mqtt.c库实现基本通信
paho_mqtt.c提供简单API。我们将编写一个发布者客户端和一个订阅者服务端。
主要函数介绍(需检查返回值):
MQTTClient_create():创建MQTT客户端实例。参数:客户端句柄指针、代理地址、客户端ID、持久存储类型。MQTTClient_connect():连接到代理。参数:客户端句柄、连接选项(包括用户名、密码等)。MQTTClient_publish():发布消息到主题。参数:客户端句柄、主题、消息长度、消息内容、QoS、保留标志。MQTTClient_subscribe():订阅主题。参数:客户端句柄、主题、QoS。MQTTClient_setCallbacks():设置消息到达回调函数。MQTTClient_disconnect():断开连接。MQTTClient_destroy():销毁客户端。
每个函数返回int类型,成功时返回MQTTCLIENT_SUCCESS(0),失败返回错误码。必须检查返回值处理错误。
代码实现:
- 发布者客户端(publisher_paho.c):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <MQTTClient.h>
#include <unistd.h>
#define ADDRESS "tcp://localhost:1883" // 代理地址
#define CLIENTID "PublisherClient"
#define TOPIC "test/topic"
#define QOS 1
#define TIMEOUT 10000L
int main() {
MQTTClient client;
MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
MQTTClient_message pubmsg = MQTTClient_message_initializer;
MQTTClient_deliveryToken token;
int rc;
// 创建客户端
rc = MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
if (rc != MQTTCLIENT_SUCCESS) {
fprintf(stderr, "Failed to create client: %d\n", rc);
exit(1);
}
// 设置连接选项
conn_opts.keepAliveInterval = 20;
conn_opts.cleansession = 1;
// 连接到代理
rc = MQTTClient_connect(client, &conn_opts);
if (rc != MQTTCLIENT_SUCCESS) {
fprintf(stderr, "Failed to connect: %d\n", rc);
MQTTClient_destroy(&client);
exit(1);
}
// 发布消息
pubmsg.payload = "Hello from Paho Publisher";
pubmsg.payloadlen = strlen(pubmsg.payload);
pubmsg.qos = QOS;
pubmsg.retained = 0;
rc = MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token);
if (rc != MQTTCLIENT_SUCCESS) {
fprintf(stderr, "Failed to publish: %d\n", rc);
MQTTClient_disconnect(client, TIMEOUT);
MQTTClient_destroy(&client);
exit(1);
}
printf("Message published. Waiting for delivery token...\n");
MQTTClient_waitForCompletion(client, token, TIMEOUT);
// 断开并清理
rc = MQTTClient_disconnect(client, TIMEOUT);
if (rc != MQTTCLIENT_SUCCESS) {
fprintf(stderr, "Failed to disconnect: %d\n", rc);
}
MQTTClient_destroy(&client);
return 0;
}
- 订阅者服务端(subscriber_paho.c):
#include <stdio.h>
#include <stdlib.h>
#include <MQTTClient.h>
#include <unistd.h>
#define ADDRESS "tcp://localhost:1883"
#define CLIENTID "SubscriberClient"
#define TOPIC "test/topic"
#define QOS 1
#define TIMEOUT 10000L
int messageArrived(void *context, char *topicName, int topicLen, MQTTClient_message *message) {
printf("Message arrived on topic: %s\n", topicName);
printf("Message: %.*s\n", message->payloadlen, (char *)message->payload);
MQTTClient_free(topicName);
MQTTClient_freeMessage(&message);
return 1;
}
int main() {
MQTTClient client;
MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
int rc;
rc = MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
if (rc != MQTTCLIENT_SUCCESS) {
fprintf(stderr, "Failed to create client: %d\n", rc);
exit(1);
}
// 设置回调
rc = MQTTClient_setCallbacks(client, NULL, NULL, messageArrived, NULL);
if (rc != MQTTCLIENT_SUCCESS) {
fprintf(stderr, "Failed to set callbacks: %d\n", rc);
MQTTClient_destroy(&client);
exit(1);
}
conn_opts.keepAliveInterval = 20;
conn_opts.cleansession = 1;
rc = MQTTClient_connect(client, &conn_opts);
if (rc != MQTTCLIENT_SUCCESS) {
fprintf(stderr, "Failed to connect: %d\n", rc);
MQTTClient_destroy(&client);
exit(1);
}
// 订阅主题
rc = MQTTClient_subscribe(client, TOPIC, QOS);
if (rc != MQTTCLIENT_SUCCESS) {
fprintf(stderr, "Failed to subscribe: %d\n", rc);
MQTTClient_disconnect(client, TIMEOUT);
MQTTClient_destroy(&client);
exit(1);
}
printf("Subscribed to topic: %s. Waiting for messages...\n", TOPIC);
while(1) {
// 保持运行以接收消息
sleep(1);
}
// 清理(实际中需处理退出信号)
rc = MQTTClient_unsubscribe(client, TOPIC);
if (rc != MQTTCLIENT_SUCCESS) fprintf(stderr, "Unsubscribe failed: %d\n", rc);
rc = MQTTClient_disconnect(client, TIMEOUT);
if (rc != MQTTCLIENT_SUCCESS) fprintf(stderr, "Disconnect failed: %d\n", rc);
MQTTClient_destroy(&client);
return 0;
}
编译和运行测试:
- 编译发布者:
gcc publisher_paho.c -o publisher_paho -lpaho-mqtt3c - 编译订阅者:
gcc subscriber_paho.c -o subscriber_paho -lpaho-mqtt3c - 运行测试:
- 启动订阅者:
./subscriber_paho(后台运行)。 - 启动发布者:
./publisher_paho。
- 启动订阅者:
- 输出结果:
- 发布者输出:
Message published. Waiting for delivery token... - 订阅者输出:
Message arrived on topic: test/topic和Message: Hello from Paho Publisher
- 发布者输出:
使用mosquitto库实现基本通信
mosquitto库提供类似功能。我们将编写发布者和订阅者。
主要函数介绍(需检查返回值):
mosquitto_new():创建mosquitto实例。参数:客户端ID、clean session标志、用户数据。mosquitto_connect():连接到代理。参数:实例、主机、端口、保持连接时间。mosquitto_publish():发布消息。参数:实例、消息ID指针、主题、消息长度、消息内容、QoS、保留标志。mosquitto_subscribe():订阅主题。参数:实例、消息ID指针、主题、QoS。mosquitto_message_callback_set():设置消息回调函数。mosquitto_disconnect():断开连接。mosquitto_destroy():销毁实例。mosquitto_loop_start():启动网络循环线程。
函数返回int,成功时返回MOSQ_ERR_SUCCESS(0),失败返回错误码。
代码实现:
- 发布者客户端(publisher_mosquitto.c):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mosquitto.h>
#include <unistd.h>
#define HOST "localhost"
#define PORT 1883
#define TOPIC "test/topic"
#define QOS 1
#define MESSAGE "Hello from Mosquitto Publisher"
int main() {
struct mosquitto *mosq = NULL;
int rc;
// 初始化库
mosquitto_lib_init();
// 创建实例
mosq = mosquitto_new(NULL, true, NULL);
if (!mosq) {
fprintf(stderr, "Failed to create client\n");
mosquitto_lib_cleanup();
return 1;
}
// 连接到代理
rc = mosquitto_connect(mosq, HOST, PORT, 60);
if (rc != MOSQ_ERR_SUCCESS) {
fprintf(stderr, "Failed to connect: %s\n", mosquitto_strerror(rc));
mosquitto_destroy(mosq);
mosquitto_lib_cleanup();
return 1;
}
// 发布消息
rc = mosquitto_publish(mosq, NULL, TOPIC, strlen(MESSAGE), MESSAGE, QOS, false);
if (rc != MOSQ_ERR_SUCCESS) {
fprintf(stderr, "Failed to publish: %s\n", mosquitto_strerror(rc));
mosquitto_disconnect(mosq);
mosquitto_destroy(mosq);
mosquitto_lib_cleanup();
return 1;
}
printf("Message published\n");
// 断开并清理
mosquitto_disconnect(mosq);
mosquitto_destroy(mosq);
mosquitto_lib_cleanup();
return 0;
}
- 订阅者服务端(subscriber_mosquitto.c):
#include <stdio.h>
#include <stdlib.h>
#include <mosquitto.h>
#include <unistd.h>
#define HOST "localhost"
#define PORT 1883
#define TOPIC "test/topic"
#define QOS 1
void message_callback(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *message) {
printf("Message arrived on topic: %s\n", message->topic);
printf("Message: %.*s\n", message->payloadlen, (char *)message->payload);
}
int main() {
struct mosquitto *mosq = NULL;
int rc;
mosquitto_lib_init();
mosq = mosquitto_new(NULL, true, NULL);
if (!mosq) {
fprintf(stderr, "Failed to create client\n");
mosquitto_lib_cleanup();
return 1;
}
// 设置回调
mosquitto_message_callback_set(mosq, message_callback);
rc = mosquitto_connect(mosq, HOST, PORT, 60);
if (rc != MOSQ_ERR_SUCCESS) {
fprintf(stderr, "Failed to connect: %s\n", mosquitto_strerror(rc));
mosquitto_destroy(mosq);
mosquitto_lib_cleanup();
return 1;
}
// 订阅主题
rc = mosquitto_subscribe(mosq, NULL, TOPIC, QOS);
if (rc != MOSQ_ERR_SUCCESS) {
fprintf(stderr, "Failed to subscribe: %s\n", mosquitto_strerror(rc));
mosquitto_disconnect(mosq);
mosquitto_destroy(mosq);
mosquitto_lib_cleanup();
return 1;
}
printf("Subscribed to topic: %s. Waiting for messages...\n", TOPIC);
mosquitto_loop_start(mosq); // 启动循环线程
while(1) {
sleep(1);
}
// 清理(实际中需处理退出信号)
mosquitto_unsubscribe(mosq, NULL, TOPIC);
mosquitto_disconnect(mosq);
mosquitto_destroy(mosq);
mosquitto_lib_cleanup();
return 0;
}
编译和运行测试:
- 编译发布者:
gcc publisher_mosquitto.c -o publisher_mosquitto -lmosquitto - 编译订阅者:
gcc subscriber_mosquitto.c -o subscriber_mosquitto -lmosquitto - 运行测试:
- 启动订阅者:
./subscriber_mosquitto(后台运行)。 - 启动发布者:
./publisher_mosquitto。
- 启动订阅者:
- 输出结果:
- 发布者输出:
Message published - 订阅者输出:
Message arrived on topic: test/topic和Message: Hello from Mosquitto Publisher
- 发布者输出:
使用MQTT+TLS实现安全通信
MQTT+TLS通过SSL/TLS加密通信,增加安全性。需要生成证书并配置代理支持TLS。
- 生成自签名证书(在Ubuntu上):
在# 创建CA证书 openssl genrsa -out ca.key 2048 openssl req -new -x509 -days 365 -key ca.key -out ca.crt # 创建服务器证书 openssl genrsa -out server.key 2048 openssl req -new -key server.key -out server.csr openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 365 # 配置Mosquitto代理 sudo cp server.crt /etc/mosquitto/certs/ sudo cp server.key /etc/mosquitto/certs/ sudo cp ca.crt /etc/mosquitto/ca_certificates/ sudo nano /etc/mosquitto/conf.d/tls.conftls.conf中添加:
重启代理:listener 8883 cafile /etc/mosquitto/ca_certificates/ca.crt certfile /etc/mosquitto/certs/server.crt keyfile /etc/mosquitto/certs/server.key require_certificate false # 简化测试,不强制客户端证书sudo systemctl restart mosquitto
-
使用paho_mqtt.c实现MQTT+TLS客户端:
修改发布者和订阅者代码,添加TLS选项。发布者MQTT+TLS(publisher_paho_tls.c):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <MQTTClient.h>
#include <unistd.h>
#define ADDRESS "tcp://localhost:1883" // 代理地址
#define CLIENTID "PublisherClient"
#define TOPIC "test/topic"
#define QOS 1
#define TIMEOUT 10000L
int main() {
MQTTClient client;
MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
MQTTClient_message pubmsg = MQTTClient_message_initializer;
MQTTClient_deliveryToken token;
int rc;
// 创建客户端
rc = MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
if (rc != MQTTCLIENT_SUCCESS) {
fprintf(stderr, "Failed to create client: %d\n", rc);
exit(1);
}
// 设置连接选项
conn_opts.keepAliveInterval = 20;
conn_opts.cleansession = 1;
//设置TLS选项
MQTTClient_SSLOptions ssl_opts = MQTTClient_SSLOptions_initializer;
conn_opts.ssl = &ssl_opts;
conn_opts.ssl->trustStore = "/etc/mosquitto/ca_certificates/ca.crt"; // CA证书路径
// 连接到代理
rc = MQTTClient_connect(client, &conn_opts);
if (rc != MQTTCLIENT_SUCCESS) {
fprintf(stderr, "Failed to connect: %d\n", rc);
MQTTClient_destroy(&client);
exit(1);
}
// 发布消息
pubmsg.payload = "Hello from Paho Publisher";
pubmsg.payloadlen = strlen(pubmsg.payload);
pubmsg.qos = QOS;
pubmsg.retained = 0;
rc = MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token);
if (rc != MQTTCLIENT_SUCCESS) {
fprintf(stderr, "Failed to publish: %d\n", rc);
MQTTClient_disconnect(client, TIMEOUT);
MQTTClient_destroy(&client);
exit(1);
}
printf("Message published. Waiting for delivery token...\n");
MQTTClient_waitForCompletion(client, token, TIMEOUT);
// 断开并清理
rc = MQTTClient_disconnect(client, TIMEOUT);
if (rc != MQTTCLIENT_SUCCESS) {
fprintf(stderr, "Failed to disconnect: %d\n", rc);
}
MQTTClient_destroy(&client);
return 0;
}
订阅者MQTT+TLS(subscriber_paho_tls.c):
#include <stdio.h>
#include <stdlib.h>
#include <MQTTClient.h>
#include <unistd.h>
#define ADDRESS "tcp://localhost:1883"
#define CLIENTID "SubscriberClient"
#define TOPIC "test/topic"
#define QOS 1
#define TIMEOUT 10000L
int messageArrived(void *context, char *topicName, int topicLen, MQTTClient_message *message) {
printf("Message arrived on topic: %s\n", topicName);
printf("Message: %.*s\n", message->payloadlen, (char *)message->payload);
MQTTClient_free(topicName);
MQTTClient_freeMessage(&message);
return 1;
}
int main() {
MQTTClient client;
MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
int rc;
rc = MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
if (rc != MQTTCLIENT_SUCCESS) {
fprintf(stderr, "Failed to create client: %d\n", rc);
exit(1);
}
// 设置回调
rc = MQTTClient_setCallbacks(client, NULL, NULL, messageArrived, NULL);
if (rc != MQTTCLIENT_SUCCESS) {
fprintf(stderr, "Failed to set callbacks: %d\n", rc);
MQTTClient_destroy(&client);
exit(1);
}
conn_opts.keepAliveInterval = 20;
conn_opts.cleansession = 1;
//设置TLS选项
MQTTClient_SSLOptions ssl_opts = MQTTClient_SSLOptions_initializer;
conn_opts.ssl = &ssl_opts;
conn_opts.ssl->trustStore = "/etc/mosquitto/ca_certificates/ca.crt"; // CA证书路径
rc = MQTTClient_connect(client, &conn_opts);
if (rc != MQTTCLIENT_SUCCESS) {
fprintf(stderr, "Failed to connect: %d\n", rc);
MQTTClient_destroy(&client);
exit(1);
}
// 订阅主题
rc = MQTTClient_subscribe(client, TOPIC, QOS);
if (rc != MQTTCLIENT_SUCCESS) {
fprintf(stderr, "Failed to subscribe: %d\n", rc);
MQTTClient_disconnect(client, TIMEOUT);
MQTTClient_destroy(&client);
exit(1);
}
printf("Subscribed to topic: %s. Waiting for messages...\n", TOPIC);
while(1) {
// 保持运行以接收消息
sleep(1);
}
// 清理(实际中需处理退出信号)
rc = MQTTClient_unsubscribe(client, TOPIC);
if (rc != MQTTCLIENT_SUCCESS) fprintf(stderr, "Unsubscribe failed: %d\n", rc);
rc = MQTTClient_disconnect(client, TIMEOUT);
if (rc != MQTTCLIENT_SUCCESS) fprintf(stderr, "Disconnect failed: %d\n", rc);
MQTTClient_destroy(&client);
return 0;
}
编译和运行测试:
- 编译发布者:
gcc publisher_paho_tls.c -o publisher_paho_tls -lpaho-mqtt3c -lssl -lcrypto - 编译订阅者:
gcc subscriber_paho_tls.c -o subscriber_paho_tls -lpaho-mqtt3c -lssl -lcrypto - 运行测试:
- 启动订阅者:
./subscriber_paho_tls(后台运行)。 - 启动发布者:
./publisher_paho_tls。
- 启动订阅者:
- 输出结果:
- 发布者输出:
Message published. Waiting for delivery token... - 订阅者输出:
Message arrived on topic: test/topic和Message: Hello from Paho Publisher
- 发布者输出:
-
使用mosquitto库实现MQTT+TLS客户端:
修改代码添加TLS。发布者MQTT+TLS(publisher_mosquitto_tls.c):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mosquitto.h>
#include <unistd.h>
#define HOST "localhost"
#define PORT 8883
#define TOPIC "test/topic"
#define QOS 1
#define MESSAGE "Hello from Mosquitto Publisher"
int main() {
struct mosquitto *mosq = NULL;
int rc;
// 初始化库
mosquitto_lib_init();
// 创建实例
mosq = mosquitto_new(NULL, true, NULL);
if (!mosq) {
fprintf(stderr, "Failed to create client\n");
mosquitto_lib_cleanup();
return 1;
}
// 设置TLS
mosquitto_tls_set(mosq, "/etc/mosquitto/ca_certificates/ca.crt", NULL, NULL, NULL, NULL); // CA证书
mosquitto_tls_insecure_set(mosq, true); // 允许自签名证书
// 连接到代理
rc = mosquitto_connect(mosq, HOST, PORT, 60);
if (rc != MOSQ_ERR_SUCCESS) {
fprintf(stderr, "Failed to connect: %s\n", mosquitto_strerror(rc));
mosquitto_destroy(mosq);
mosquitto_lib_cleanup();
return 1;
}
// 发布消息
rc = mosquitto_publish(mosq, NULL, TOPIC, strlen(MESSAGE), MESSAGE, QOS, false);
if (rc != MOSQ_ERR_SUCCESS) {
fprintf(stderr, "Failed to publish: %s\n", mosquitto_strerror(rc));
mosquitto_disconnect(mosq);
mosquitto_destroy(mosq);
mosquitto_lib_cleanup();
return 1;
}
printf("Message published\n");
// 断开并清理
mosquitto_disconnect(mosq);
mosquitto_destroy(mosq);
mosquitto_lib_cleanup();
return 0;
}
编译:gcc publisher_mosquitto_tls.c -o publisher_mosquitto_tls -lmosquitto -lssl -lcrypto
订阅者TLS(subscriber_mosquitto_tls.c):
#include <stdio.h>
#include <stdlib.h>
#include <mosquitto.h>
#include <unistd.h>
#define HOST "localhost"
#define PORT 8883
#define TOPIC "test/topic"
#define QOS 1
void message_callback(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *message) {
printf("Message arrived on topic: %s\n", message->topic);
printf("Message: %.*s\n", message->payloadlen, (char *)message->payload);
}
int main() {
struct mosquitto *mosq = NULL;
int rc;
mosquitto_lib_init();
mosq = mosquitto_new(NULL, true, NULL);
if (!mosq) {
fprintf(stderr, "Failed to create client\n");
mosquitto_lib_cleanup();
return 1;
}
// 设置TLS
mosquitto_tls_set(mosq, "/etc/mosquitto/ca_certificates/ca.crt", NULL, NULL, NULL, NULL); // CA证书
mosquitto_tls_insecure_set(mosq, true); // 允许自签名证书
// 设置回调
mosquitto_message_callback_set(mosq, message_callback);
rc = mosquitto_connect(mosq, HOST, PORT, 60);
if (rc != MOSQ_ERR_SUCCESS) {
fprintf(stderr, "Failed to connect: %s\n", mosquitto_strerror(rc));
mosquitto_destroy(mosq);
mosquitto_lib_cleanup();
return 1;
}
// 订阅主题
rc = mosquitto_subscribe(mosq, NULL, TOPIC, QOS);
if (rc != MOSQ_ERR_SUCCESS) {
fprintf(stderr, "Failed to subscribe: %s\n", mosquitto_strerror(rc));
mosquitto_disconnect(mosq);
mosquitto_destroy(mosq);
mosquitto_lib_cleanup();
return 1;
}
printf("Subscribed to topic: %s. Waiting for messages...\n", TOPIC);
mosquitto_loop_start(mosq); // 启动循环线程
while(1) {
sleep(1);
}
// 清理(实际中需处理退出信号)
mosquitto_unsubscribe(mosq, NULL, TOPIC);
mosquitto_disconnect(mosq);
mosquitto_destroy(mosq);
mosquitto_lib_cleanup();
return 0;
}
编译和运行测试:
- 编译发布者:
gcc publisher_mosquitto_tls.c -o publisher_mosquitto_tls -lmosquitto - 编译订阅者:
gcc subscriber_mosquitto_tls.c -o subscriber_mosquitto_tls -lmosquitto - 运行测试:
- 启动订阅者:
./subscriber_mosquitto_tls(后台运行)。 - 启动发布者:
./publisher_mosquitto_tls。
- 启动订阅者:
- 输出结果:
- 发布者输出:
Message published - 订阅者输出:
Message arrived on topic: test/topic和Message: Hello from Mosquitto Publisher
- 发布者输出:
Paho 与 Mosquitto 对比
| 特性 | Paho MQTT C | Mosquitto |
|---|---|---|
| 定位 | 客户端库 | 代理 + 客户端库 |
| 线程模型 | 异步回调 | 同步/异步可选 |
| TLS支持 | 需编译开启 | 默认支持 |
| 适用场景 | 嵌入式设备、轻量应用 | 服务端部署、全功能 |
通过以上步骤,您可以在 Ubuntu 上完整实现 MQTT 通信,并进一步扩展至加密通信场景。
更多推荐


所有评论(0)