使用开源C语言库连接MQTT Broker
(图片来源网络,侵删)在物联网(IoT)和嵌入式系统开发中,MQTT(Message Queuing Telemetry Transport)协议因其轻量级、开放标准和易于实现的特点而广受欢迎,连接MQTT Broker允许设备通过互联网发送和接收消息,实现远程通信和控制,本文将指导您如何使用开源C语言库来连接MQTT Broker。
准备工作
确保您已经安装了必要的开发工具和库,对于大多数Linux系统,可以使用包管理器安装所需的库和编译器,在Ubuntu系统中,可以使用以下命令:
sudo aptget update sudo aptget install gcc libpahomqttpp3dev
这将安装GCC编译器和Paho MQTT C++库,后者是一个流行的MQTT客户端库,支持C和C++。
创建MQTT客户端
创建一个名为mqtt_client.c的源文件,并编写以下代码以包含必要的头文件和定义回调函数:
#include#include #include #include "MQTTClient.h" static void delivered(void* context, MQTTClient_deliveryToken dt) { printf("Message with token value %d delivery confirmed ", dt); MQTTClient_free(dt); } int main(int argc, char* argv[]) { // MQTT客户端初始化代码将在这里添加 return 0; }
初始化MQTT客户端
(图片来源网络,侵删)在main函数中添加以下代码以初始化MQTT客户端:
int main(int argc, char* argv[]) { MQTTClient client; MQTTClient_create(&client, "tcp://broker.example.com", "ClientID", MQTTCLIENT_PERSISTENCE_NONE, NULL); MQTTClient_setCallbacks(client, NULL, connlost, delivered, NULL); // 连接到MQTT Broker的代码将在这里添加 // 发布和订阅消息的代码也将在这里添加 MQTTClient_destroy(&client); return 0; }这里,我们创建了一个指向MQTT客户端的指针,指定了MQTT Broker的地址(请替换为实际的Broker地址),客户端ID以及不需要持久性存储,我们还设置了回调函数来处理连接丢失和消息交付确认事件。
连接到MQTT Broker
继续在main函数中添加以下代码以连接到MQTT Broker:
int main(int argc, char* argv[]) { // ...之前的代码... int rc; if ((rc = MQTTClient_connect(client, NULL)) != MQTTCLIENT_SUCCESS) { printf("Failed to connect, return code %d ", rc); exit(EXIT_FAILURE); } printf("Connected to MQTT Broker "); // ...之后的代码... }这段代码尝试连接到MQTT Broker,并在失败时打印错误代码并退出程序,成功连接后,会输出一条确认信息。
发布和订阅消息
我们将添加代码来订阅主题并发布消息:
(图片来源网络,侵删) int main(int argc, char* argv[]) { // ...之前的代码... const char* topic = "my/test/topic"; char msg[100]; int QOS = 1; // 订阅主题 if ((rc = MQTTClient_subscribe(client, topic, QOS)) != MQTTCLIENT_SUCCESS) { printf("Failed to subscribe, return code %d ", rc); exit(EXIT_FAILURE); } printf("Subscribed to topic '%s' ", topic); // 发布消息 snprintf(msg, sizeof(msg), "Hello, MQTT!"); if ((rc = MQTTClient_publish(client, topic, msg, strlen(msg)+1, QOS, 0, delivered)) != MQTTCLIENT_SUCCESS) { printf("Failed to publish, return code %d ", rc); exit(EXIT_FAILURE); } printf("Published message: '%s' ", msg); // ...之后的代码... }我们首先定义了一个主题字符串和一个用于存储消息的缓冲区,我们调用MQTTClient_subscribe函数订阅主题,并检查是否成功,之后,我们使用snprintf函数格式化一条消息,并使用MQTTClient_publish函数将该消息发布到订阅的主题上。
完整示例代码
将以上所有代码片段合并,完整的mqtt_client.c文件应该如下所示:
#include#include #include #include "MQTTClient.h" static void delivered(void* context, MQTTClient_deliveryToken dt) { printf("Message with token value %d delivery confirmed ", dt); MQTTClient_free(dt); } int main(int argc, char* argv[]) { MQTTClient client; MQTTClient_create(&client, "tcp://broker.example.com", "ClientID", MQTTCLIENT_PERSISTENCE_NONE, NULL); MQTTClient_setCallbacks(client, NULL, connlost, delivered, NULL); int rc; if ((rc = MQTTClient_connect(client, NULL)) != MQTTCLIENT_SUCCESS) { printf("Failed to connect, return code %d ", rc); exit(EXIT_FAILURE); } printf("Connected to MQTT Broker "); const char* topic = "my/test/topic"; char msg[100]; int QOS = 1; if ((rc = MQTTClient_subscribe(client, topic, QOS)) != MQTTCLIENT_SUCCESS) { printf("Failed to subscribe, return code %d ", rc); exit(EXIT_FAILURE); } printf("Subscribed to topic '%s' ", topic); snprintf(msg, sizeof(msg), "Hello, MQTT!"); if ((rc = MQTTClient_publish(client, topic, msg, strlen(msg)+1, QOS, 0, delivered)) != MQTTCLIENT_SUCCESS) { printf("Failed to publish, return code %d ", rc); exit(EXIT_FAILURE); } printf("Published message: '%s' ", msg); MQTTClient_destroy(&client); return 0; }
编译并运行这个程序,确保您的设备已连接到互联网并且能够访问指定的MQTT Broker,如果一切正常,您应该会看到程序输出连接成功、订阅成功和发布成功的消息。
相关问答FAQs
Q1: 如果我想使用TLS加密连接到MQTT Broker,应该如何修改代码?
A1: 要使用TLS加密连接到MQTT Broker,您需要指定一个带有TLS证书的上下文,并在创建MQTT客户端时使用该上下文,这通常涉及到加载CA证书和可能的客户证书/密钥,具体步骤包括加载证书、创建TLS上下文、设置MQTT客户端选项以使用该上下文,然后像之前一样创建和连接客户端,需要注意的是,这可能需要额外的库,如OpenSSL。
Q2: 我如何在一个嵌入式设备上运行这个MQTT客户端?
A2: 要在嵌入式设备上运行MQTT客户端,您需要确保设备具有足够的资源(如内存和处理能力)来运行客户端代码和支持的网络连接,您需要在嵌入式设备上安装必要的开发工具和库,这可能涉及到交叉编译工具链的使用,以便在您的开发机器上为嵌入式设备架构编译代码,一旦编译完成,您可以将生成的二进制文件部署到嵌入式设备上,并确保设备配置了正确的网络设置以连接到MQTT Broker。
下面是一个简化的介绍,展示了如何使用开源C语言库连接MQTT Broker,这里以常用的两个库为例:Eclipse Paho 和MQTTClient。
| 库名称 | 网站链接 | 安装指南 | 连接示例 |
| Eclipse Paho | [Paho官网](https://www.eclipse.org/paho/index.php) | git clone https://github.com/eclipse/paho.mqtt.c.git,然后按照README中的编译指南操作 | |
| MQTTClient | [MQTTClient官网](https://www.eclipse.org/paho/index.php?page=clients/c/index.php) | 下载源码或使用包管理器安装,如:aptget 或brew |
下面是这两个库的基本连接示例。
Eclipse Paho 示例
#include "stdio.h" #include "stdlib.h" #include "string.h" #include "MQTTClient.h" #define ADDRESS "tcp://broker.hivemq.com:1883" #define CLIENTID "ExampleClientPub" #define TOPIC "test/topic" #define PAYLOAD "Hello World!" #define QOS 1 #define TIMEOUT 10000L int main(int argc, char* argv[]) { MQTTClient client; MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer; MQTTClient_message pubmsg = MQTTClient_message_initializer; MQTTClient_deliveryToken token; int rc; MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL); conn_opts.keepAliveInterval = 20; conn_opts.cleansession = 1; if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) { printf("Failed to connect, return code %d ", rc); exit(1); } pubmsg.payload = PAYLOAD; pubmsg.payloadlen = strlen(PAYLOAD); pubmsg.qos = QOS; pubmsg.retained = 0; MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token); MQTTClient_waitForCompletion(client, token, TIMEOUT); MQTTClient_disconnect(client, 10000); MQTTClient_destroy(&client); return rc; }MQTTClient 示例
#include "stdio.h" #include "stdlib.h" #include "string.h" #include "MQTTClient.h" #define ADDRESS "tcp://broker.hivemq.com:1883" #define CLIENTID "ExampleClientPub" #define TOPIC "test/topic" #define PAYLOAD "Hello World!" #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; MQTTClient_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL); conn_opts.keepAliveInterval = 20; conn_opts.cleansession = 1; if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS) { printf("Failed to connect, return code %d ", rc); exit(1); } MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token); MQTTClient_waitForCompletion(client, token, TIMEOUT); MQTTClient_disconnect(client, 10000); MQTTClient_destroy(&client); return rc; }请注意,以上示例可能需要根据库的具体版本和API进行适当的调整,连接到MQTT Broker时,确保Broker的地址、端口、客户端ID、用户名和密码等配置是正确的。