谷动谷力

 找回密码
 立即注册
查看: 916|回复: 0
打印 上一主题 下一主题
收起左侧

使用Mosquitto实现MQTT客户端C语言

[复制链接]
跳转到指定楼层
楼主
发表于 2023-11-20 23:38:14 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
使用Mosquitto实现MQTT客户端C语言




  上一篇文章已经将mosquitto移植到了arm平台上,现在将使用mosquitto完成mqtt客服端的demo,了解过mqtt协议的小伙伴都知道,mqtt主要分为代理服务器、发布者、订阅者三部分。接下来通过mqtt发布者和订阅者两个demo了解mosquitto库函数的使用。

一、Mosquitto库函数的API
mosquitto的api说明文档:https://mosquitto.org/api/files/mosquitto-h.html
mosquitto库中常见的函数应用总结:https://blog.csdn.net/makunIT/article/details/107283260
上面这位博主总结的比较好,我就在这里引用一下,需要的小伙伴可以看看。

二、mqtt发布者源码
mqtt_pub_demo.c
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <mosquitto.h>
  4. #include <string.h>

  5. #define HOST "192.168.2.99"
  6. #define PORT  1883
  7. #define KEEP_ALIVE 60
  8. #define MSG_MAX_SIZE  512

  9. bool session = true;

  10. int main(void)
  11. {

  12.     int err = 0;

  13.     printf("mqtt publish init...\n");
  14.     struct mosquitto *mosq = NULL;
  15.     char buff[MSG_MAX_SIZE];

  16.     //libmosquitto 库初始化
  17.     err = mosquitto_lib_init();
  18.     if (err < 0){
  19.         printf("mosquitto lib int fail...");
  20.         goto fail_mosquitto_lib;
  21.     }

  22.     //创建mosquitto客户端
  23.     mosq = mosquitto_new(NULL,session,NULL);
  24.     if (mosq == NULL){
  25.         printf("create client failed...\n");
  26.         err = -1;
  27.         goto fail_mosquitto_new;
  28.     }

  29.     //客户端连接服务器
  30.     err = mosquitto_connect(mosq, HOST, PORT, KEEP_ALIVE);
  31.     if (err < 0){
  32.         printf("connect fail");   
  33.         goto fail_mosq_conn;
  34.     }

  35.     //不阻塞,库函数中将自动创建线程实现
  36.     err = mosquitto_loop_start(mosq);
  37.     if(err != MOSQ_ERR_SUCCESS){
  38.         printf("mosquitto loop error\n");
  39.         goto fail_mosq_loop_start;
  40.     }

  41.     while(fgets(buff, MSG_MAX_SIZE, stdin) != NULL)
  42.     {
  43.         mosquitto_publish(mosq, NULL, "temp", strlen(buff)+1, buff, 0, 0);
  44.         memset(buff, 0, sizeof(buff));
  45.     }

  46.     mosquitto_disconnect(mosq);
  47.     mosquitto_loop_stop(mosq, true);
  48.     mosquitto_destroy(mosq);
  49.     mosquitto_lib_cleanup();

  50.     return 0;
  51. fail_mosq_loop_start:
  52.     mosquitto_disconnect(mosq);
  53. fail_mosq_conn:
  54.     mosquitto_destroy(mosq);
  55. fail_mosquitto_new:
  56.     mosquitto_lib_cleanup();
  57. fail_mosquitto_lib:
  58.     return err;
  59. }
复制代码

Makefile
  1. INCLUDES = -lmosquitto -lpthread -ldl -lssl -lcrypto  \
  2. -I/home/linux/arm-lib/mosquitto/include \
  3. -L/home/linux/arm-lib/mosquitto/lib \
  4. -L/homelinux/arm-lib/openssl/lib

  5. SOURCE = $(wildcard ./*.c)

  6. OBJ = $(patsubst ./%.c, ./%.0, $(SOURCE))

  7. #INCLUDES = $(wildcard ./*.h)

  8. TARGET = mqtt_pub_demo
  9. CC = arm-linux-gnueabihf-gcc

  10. $(TARGET):$(OBJ)
  11.     $(CC) $(OBJ) -o $(TARGET) $(INCLUDES)

  12. %.0:%.c
  13.     $(CC) -c [        DISCUZ_CODE_15        ]lt; -o $[url=home.php?mod=space&uid=19945]@[/url] $(INCLUDES)

  14. clean:
  15.     rm -rf $(OBJ) $(TARGET)
复制代码

三、mqtt订阅者源码
mqtt_sub_demo.c
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <mosquitto.h>
  4. #include <string.h>

  5. #define HOST "192.168.2.99"
  6. #define PORT  1883
  7. #define KEEP_ALIVE 60

  8. bool session = true;

  9. void mqtt_subscribe_callback(struct mosquitto *mosq,
  10.                 void *userdata, int mid, int qos_count, const int *granted_qos)
  11. {
  12.     int i;
  13.     printf("subscribed (mid: %d): %d", mid, granted_qos[0]);
  14.     for(i=1; i < qos_count; i++){
  15.         printf(", %d", granted_qos[i]);
  16.     }
  17.     printf("\n");
  18. }

  19. //消息回调函数,收到订阅的消息后调用
  20. void mqtt_message_callback(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *message)
  21. {
  22.     if (message->payloadlen){
  23.         printf("%s %s \n", message->topic, (char *)message->payload);
  24.     }else{
  25.         printf("%s (null)\n",message->topic);
  26.     }
  27. }

  28. //mqtt连接回调
  29. void mqtt_connect_callback(struct mosquitto *mosq, void *userdata, int result)
  30. {
  31.     int ret;
  32.     if (!result){
  33.         ret = mosquitto_subscribe(mosq, NULL, "temp", 2);
  34.         if(ret < 0){
  35.             printf("Subscription failed\n");
  36.         }else{
  37.             printf("Subscription succeeded\n");
  38.         }
  39.     }else{
  40.         printf("connect failed\n");
  41.     }
  42. }

  43. //日志回调函数
  44. void mqtt_log_callback(struct mosquitto *mosq, void *userdata, int level, const char *str)
  45. {
  46.     printf("log__   %s\n", str);   
  47. }

  48. int main(void)
  49. {

  50.     int err = 0;
  51.     printf("mqtt client init...\n");

  52.     struct mosquitto *mosq = NULL;

  53.     //libmosquitto 库初始化
  54.     err = mosquitto_lib_init();
  55.     if (err < 0){
  56.         printf("mosquitto lib int fail...");
  57.         goto fail_mosquitto_lib;
  58.     }

  59.     //创建mosquitto客户端
  60.     mosq = mosquitto_new(NULL,session,NULL);
  61.     if (mosq == NULL){
  62.         printf("create client failed...\n");
  63.         err = -1;
  64.         goto fail_mosquitto_new;
  65.     }

  66.     //设置回调函数
  67.     mosquitto_log_callback_set(mosq, mqtt_log_callback);
  68.     mosquitto_connect_callback_set(mosq, mqtt_connect_callback);
  69.     mosquitto_message_callback_set(mosq, mqtt_message_callback);
  70.     mosquitto_subscribe_callback_set(mosq, mqtt_subscribe_callback);

  71.     //客户端连接服务器
  72.     err = mosquitto_connect(mosq, HOST, PORT, KEEP_ALIVE);
  73.     if (err < 0){
  74.         printf("connect fail");   
  75.         goto fail_mosq_conn;
  76.     }
  77.    
  78.     //主线成将被阻塞至此
  79.     err = mosquitto_loop_forever(mosq, -1, 1);
  80.     if (err < 0){
  81.         printf("mosquitto loop fail");
  82.         goto fail_mosq_loop_stop;
  83.     }

  84.     mosquitto_disconnect(mosq);
  85.     mosquitto_loop_stop(mosq, false);
  86.     mosquitto_destroy(mosq);
  87.     mosquitto_lib_cleanup();

  88.     return 0;

  89. fail_mosq_loop_stop:
  90.     mosquitto_disconnect(mosq);
  91. fail_mosq_conn:
  92.     mosquitto_destroy(mosq);
  93. fail_mosquitto_new:
  94.     mosquitto_lib_cleanup();
  95. fail_mosquitto_lib:
  96.     return err;
  97. }
复制代码

Makefile
  1. INCLUDES = -lmosquitto -lpthread -ldl -lssl -lcrypto  \
  2. -I/home/xfg/linux/arm-lib/mosquitto/include \
  3. -L/home/xfg/linux/arm-lib/mosquitto/lib \
  4. -L/home/xfg/linux/arm-lib/openssl/lib

  5. SOURCE = mqtt_sub_demo.c

  6. TARGET = mqtt_sub_demo
  7. CC = arm-linux-gnueabihf-gcc

  8. $(TARGET):$(SOURCE)
  9.     $(CC) $(SOURCE) -o $(TARGET) $(INCLUDES)

  10. clean:
  11.     rm -rf $(TARGET)
复制代码

四、测试
  • 在虚拟机上打开代理服务器,并将编译生成的mqtt_sub_demo和mqtt_pub_demo移动到ARM开发版上
  • 打开mqqt订阅者
  • 打开mqtt发布者,发布信息

    完成后,可以看订阅者接受的信息是否正确

    由此可以看出编写的测试程序没问题。

五、参考文献
mosquitto库中常见的函数应用总结:https://blog.csdn.net/makunIT/article/details/107283260
基于MQTT协议的Mosquitto的使用及libmosquitto客户端编程:https://blog.csdn.net/danwuxie/article/details/86517568
基于mosquitto的MQTT客户端实现C语言:https://www.cnblogs.com/y-c-y/p/11686916.html
Qt官方MQTT库的使用,附一个MqttClient例子:https://www.cnblogs.com/yexiaopeng/p/8542894.html
mosquitto的api说明文档:https://mosquitto.org/api/files/mosquitto-h.html
+10
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|深圳市光明谷科技有限公司|光明谷商城|Sunshine Silicon Corpporation ( 粤ICP备14060730号|Sitemap

GMT+8, 2024-5-20 09:26 , Processed in 0.122551 second(s), 43 queries .

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表