|
使用Mosquitto实现MQTT客户端C语言
上一篇文章已经将mosquitto移植到了arm平台上,现在将使用mosquitto完成mqtt客服端的demo,了解过mqtt协议的小伙伴都知道,mqtt主要分为代理服务器、发布者、订阅者三部分。接下来通过mqtt发布者和订阅者两个demo了解mosquitto库函数的使用。
一、Mosquitto库函数的API
二、mqtt发布者源码
mqtt_pub_demo.c - #include <stdio.h>
- #include <stdlib.h>
- #include <mosquitto.h>
- #include <string.h>
- #define HOST "192.168.2.99"
- #define PORT 1883
- #define KEEP_ALIVE 60
- #define MSG_MAX_SIZE 512
- bool session = true;
- int main(void)
- {
- int err = 0;
- printf("mqtt publish init...\n");
- struct mosquitto *mosq = NULL;
- char buff[MSG_MAX_SIZE];
- //libmosquitto 库初始化
- err = mosquitto_lib_init();
- if (err < 0){
- printf("mosquitto lib int fail...");
- goto fail_mosquitto_lib;
- }
- //创建mosquitto客户端
- mosq = mosquitto_new(NULL,session,NULL);
- if (mosq == NULL){
- printf("create client failed...\n");
- err = -1;
- goto fail_mosquitto_new;
- }
- //客户端连接服务器
- err = mosquitto_connect(mosq, HOST, PORT, KEEP_ALIVE);
- if (err < 0){
- printf("connect fail");
- goto fail_mosq_conn;
- }
- //不阻塞,库函数中将自动创建线程实现
- err = mosquitto_loop_start(mosq);
- if(err != MOSQ_ERR_SUCCESS){
- printf("mosquitto loop error\n");
- goto fail_mosq_loop_start;
- }
- while(fgets(buff, MSG_MAX_SIZE, stdin) != NULL)
- {
- mosquitto_publish(mosq, NULL, "temp", strlen(buff)+1, buff, 0, 0);
- memset(buff, 0, sizeof(buff));
- }
- mosquitto_disconnect(mosq);
- mosquitto_loop_stop(mosq, true);
- mosquitto_destroy(mosq);
- mosquitto_lib_cleanup();
- return 0;
- fail_mosq_loop_start:
- mosquitto_disconnect(mosq);
- fail_mosq_conn:
- mosquitto_destroy(mosq);
- fail_mosquitto_new:
- mosquitto_lib_cleanup();
- fail_mosquitto_lib:
- return err;
- }
复制代码
Makefile - INCLUDES = -lmosquitto -lpthread -ldl -lssl -lcrypto \
- -I/home/linux/arm-lib/mosquitto/include \
- -L/home/linux/arm-lib/mosquitto/lib \
- -L/homelinux/arm-lib/openssl/lib
- SOURCE = $(wildcard ./*.c)
- OBJ = $(patsubst ./%.c, ./%.0, $(SOURCE))
- #INCLUDES = $(wildcard ./*.h)
- TARGET = mqtt_pub_demo
- CC = arm-linux-gnueabihf-gcc
- $(TARGET):$(OBJ)
- $(CC) $(OBJ) -o $(TARGET) $(INCLUDES)
- %.0:%.c
- $(CC) -c [ DISCUZ_CODE_15 ]lt; -o $[url=home.php?mod=space&uid=19945]@[/url] $(INCLUDES)
- clean:
- rm -rf $(OBJ) $(TARGET)
复制代码
三、mqtt订阅者源码
mqtt_sub_demo.c - #include <stdio.h>
- #include <stdlib.h>
- #include <mosquitto.h>
- #include <string.h>
- #define HOST "192.168.2.99"
- #define PORT 1883
- #define KEEP_ALIVE 60
- bool session = true;
- void mqtt_subscribe_callback(struct mosquitto *mosq,
- void *userdata, int mid, int qos_count, const int *granted_qos)
- {
- int i;
- printf("subscribed (mid: %d): %d", mid, granted_qos[0]);
- for(i=1; i < qos_count; i++){
- printf(", %d", granted_qos[i]);
- }
- printf("\n");
- }
- //消息回调函数,收到订阅的消息后调用
- void mqtt_message_callback(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *message)
- {
- if (message->payloadlen){
- printf("%s %s \n", message->topic, (char *)message->payload);
- }else{
- printf("%s (null)\n",message->topic);
- }
- }
- //mqtt连接回调
- void mqtt_connect_callback(struct mosquitto *mosq, void *userdata, int result)
- {
- int ret;
- if (!result){
- ret = mosquitto_subscribe(mosq, NULL, "temp", 2);
- if(ret < 0){
- printf("Subscription failed\n");
- }else{
- printf("Subscription succeeded\n");
- }
- }else{
- printf("connect failed\n");
- }
- }
- //日志回调函数
- void mqtt_log_callback(struct mosquitto *mosq, void *userdata, int level, const char *str)
- {
- printf("log__ %s\n", str);
- }
- int main(void)
- {
- int err = 0;
- printf("mqtt client init...\n");
- struct mosquitto *mosq = NULL;
- //libmosquitto 库初始化
- err = mosquitto_lib_init();
- if (err < 0){
- printf("mosquitto lib int fail...");
- goto fail_mosquitto_lib;
- }
- //创建mosquitto客户端
- mosq = mosquitto_new(NULL,session,NULL);
- if (mosq == NULL){
- printf("create client failed...\n");
- err = -1;
- goto fail_mosquitto_new;
- }
- //设置回调函数
- mosquitto_log_callback_set(mosq, mqtt_log_callback);
- mosquitto_connect_callback_set(mosq, mqtt_connect_callback);
- mosquitto_message_callback_set(mosq, mqtt_message_callback);
- mosquitto_subscribe_callback_set(mosq, mqtt_subscribe_callback);
- //客户端连接服务器
- err = mosquitto_connect(mosq, HOST, PORT, KEEP_ALIVE);
- if (err < 0){
- printf("connect fail");
- goto fail_mosq_conn;
- }
-
- //主线成将被阻塞至此
- err = mosquitto_loop_forever(mosq, -1, 1);
- if (err < 0){
- printf("mosquitto loop fail");
- goto fail_mosq_loop_stop;
- }
- mosquitto_disconnect(mosq);
- mosquitto_loop_stop(mosq, false);
- mosquitto_destroy(mosq);
- mosquitto_lib_cleanup();
- return 0;
- fail_mosq_loop_stop:
- mosquitto_disconnect(mosq);
- fail_mosq_conn:
- mosquitto_destroy(mosq);
- fail_mosquitto_new:
- mosquitto_lib_cleanup();
- fail_mosquitto_lib:
- return err;
- }
复制代码
Makefile - INCLUDES = -lmosquitto -lpthread -ldl -lssl -lcrypto \
- -I/home/xfg/linux/arm-lib/mosquitto/include \
- -L/home/xfg/linux/arm-lib/mosquitto/lib \
- -L/home/xfg/linux/arm-lib/openssl/lib
- SOURCE = mqtt_sub_demo.c
- TARGET = mqtt_sub_demo
- CC = arm-linux-gnueabihf-gcc
- $(TARGET):$(SOURCE)
- $(CC) $(SOURCE) -o $(TARGET) $(INCLUDES)
- clean:
- rm -rf $(TARGET)
复制代码
四、测试- 在虚拟机上打开代理服务器,并将编译生成的mqtt_sub_demo和mqtt_pub_demo移动到ARM开发版上
- 打开mqqt订阅者
- 打开mqtt发布者,发布信息
完成后,可以看订阅者接受的信息是否正确
由此可以看出编写的测试程序没问题。
五、参考文献
|
+10
|