范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

mqtt应用于进程间通信

  前言
  上一篇分享了:简单认识认识mqtt及mosquitto ,但也只是分享了mqtt的一些概念及mosquitto的一些介绍。这不,就有读者来催更了:
  这一篇我们就来分享mqtt应用于进程间通信的实例。我们沿用例说嵌入式实用知识之JSON数据 这篇文章的综合demo来改造改造。那个综合demo的功能是这样子的:
  这是以socket来作为进程间通信的方式,并且这个demo是基于Windows写的,需要包含Windows特定的头文件。
  本篇笔记我们把上面这个综合demo改为:
  我们用mqtt来作为进程间通信的方式,在Linux下进程测试。
  先贴代码:json_print进程源码
  json_print.c:/* - 程序功能: 组JSON格式数据包并发送(MQTT发布者客户端程序) - 编译命令: gcc cJSON.c json_print.c -L ../mosquitto/build/lib -lmosquitto -o json_print - 导出mosquitto动态库: export LD_LIBRARY_PATH=../mosquitto/build/lib:$LD_LIBRARY_PATH - 作者:ZhengN - 公众号:嵌入式大杂烩 */  #include  #include  #include  #include "cJSON.h" #include "../mosquitto/lib/mosquitto.h"  #define  STU_NAME_LEN  32  /* 学生结构体 */ typedef struct _Student {     char name[STU_NAME_LEN];  // 名字           int num;                  // 学号           int c_score;              // C语言分数 }StudentDef, *pStudentDef;  /* 内部函数声明 */ static StudentDef StudentData_Prepare(void); static char *StudentsData_Packet(pStudentDef _Stu); static void StudentData_Send(const char *_data); static void MqttClientInit(void); static void MqttClientClean(void);  bool clean_session = true; struct mosquitto *mosq = NULL;  /******************************************************************************************************** ** 函数: main **------------------------------------------------------------------------------------------------------ ** 参数:  ** 说明:  ** 返回:  ********************************************************************************************************/ int main(void) {     StudentDef stu = {0};     char *stu_data = NULL;     int stu_count = 0;     int i = 0;      /* MQTT客户端初始化 */     MqttClientInit();      /* 需要登记的学生总人数 */     printf("Please input number of student: ");     scanf("%d", &stu_count);      while (i++ < stu_count)     {         /* 准备数据 */         stu = StudentData_Prepare();          /* JSON格式数据组包 */         stu_data = StudentsData_Packet(&stu);          /* 发送数据 */         StudentData_Send(stu_data);     }      /* 回收操作 */     MqttClientClean();      return 0; }  /******************************************************************************************************** ** 函数: StudentData_Prepare, 准备组包需要的数据 **------------------------------------------------------------------------------------------------------ ** 参数:  ** 说明:  ** 返回: 获取得到的数据 ********************************************************************************************************/ static StudentDef StudentData_Prepare(void) {     char name[STU_NAME_LEN] = {0};     int num = 0;     int c_score = 0;     StudentDef stu;      /* 名字 */     printf("Please input name: ");     scanf("%s", name);     if (strlen(name) < STU_NAME_LEN)     {         strncpy((char*)&stu.name, name, strlen(name)+1);     }     else     {         printf("The name is too long ");     }          /* 学号 */     printf("Please input num (0~100): ");     scanf("%d", &num);     stu.num = num;      /* C语言分数 */     printf("Please input c_score (0~100): ");     scanf("%d", &c_score);     stu.c_score = c_score;      return stu; }  /******************************************************************************************************** ** 函数: StudentsData_Packet, JSON格式数据组包 **------------------------------------------------------------------------------------------------------ ** 参数: _Stu:组student json数据包需要的数据 ** 说明:  ** 返回: JSON格式的字符串    ********************************************************************************************************/ static char *StudentsData_Packet(pStudentDef _Stu) {     char *res_string = NULL;    // 返回值     cJSON *name = NULL;         // 名字     cJSON *num = NULL;          // 学号     cJSON *c_score = NULL;      // C语言分数      /* 创建一个JSON对象,{}扩起来 */     cJSON *obj = cJSON_CreateObject();     if (obj == NULL)     {         goto end;     }      /* 创建 "name": "xxx" 键值对 */     name = cJSON_CreateString(_Stu->name);     if (name == NULL)     {         goto end;     }     cJSON_AddItemToObject(obj, "name", name);      /* 创建 "num": 207 键值对 */     num = cJSON_CreateNumber(_Stu->num);     if (name == NULL)     {         goto end;     }     cJSON_AddItemToObject(obj, "num", num);          /* 创建 "c_score": 95 键值对 */     c_score = cJSON_CreateNumber(_Stu->c_score);     if (name == NULL)     {         goto end;     }     cJSON_AddItemToObject(obj, "c_score", c_score);       res_string = cJSON_Print(obj);          // 呈现为JSON格式      // res_string = cJSON_PrintUnformatted(obj);   // 呈现为无格式      if (res_string == NULL)     {         fprintf(stderr, "Failed to print monitor. ");     }  /* 异常情况统一Delete(free) */ end:     cJSON_Delete(obj);     return res_string; }  /******************************************************************************************************** ** 函数: StudentData_Send, JSON格式字符串数据组包发送 **------------------------------------------------------------------------------------------------------ ** 参数: _data:要发送的数据 ** 说明:  ** 返回: JSON格式的字符串    ********************************************************************************************************/ static void StudentData_Send(const char *_data) {     printf("%s: %s  ", __FUNCTION__, _data);      /* 发布消息 */     mosquitto_publish(mosq, NULL, "test_topic", strlen(_data)+1, (const char*)_data, 0, 0); }  /******************************************************************************************************** ** 函数: MqttClientInit, MQTT客户端初始化 **------------------------------------------------------------------------------------------------------ ** 参数: void ** 说明:  ** 返回:  ********************************************************************************************************/ static void MqttClientInit(void) {     /* libmosquitto 库初始化 */     mosquitto_lib_init();      /* 创建mosquitto客户端 */     mosq = mosquitto_new(NULL, clean_session, NULL);     if(NULL == mosq)     {         printf("Create mqtt client failed... ");         mosquitto_lib_cleanup();         return;     }      /* 连接服务器 */     if(mosquitto_connect(mosq, "localhost", 1883, 60))     {         printf("Unable to connect... ");         return;     }      /* 网络消息处理线程 */     int loop = mosquitto_loop_start(mosq);     if(loop != MOSQ_ERR_SUCCESS)     {         printf("mosquitto loop error ");         return;     } }  /******************************************************************************************************** ** 函数: MqttClientClean, MQTT客户端清理操作 **------------------------------------------------------------------------------------------------------ ** 参数: void ** 说明:  ** 返回:  ********************************************************************************************************/ static void MqttClientClean(void) {     mosquitto_destroy(mosq);     mosquitto_lib_cleanup(); }json_parse进程源码
  json_parse.c:/* - 程序功能: 接收JSON数据并解析(MQTT订阅者客户端程序) - 编译命令: gcc cJSON.c json_parse.c -L ../mosquitto/build/lib -lmosquitto -o json_parse - 导出mosquitto动态库: export LD_LIBRARY_PATH=../mosquitto/build/lib:$LD_LIBRARY_PATH - 作者:ZhengN - 公众号:嵌入式大杂烩 */  #include  #include  #include  #include "cJSON.h" #include "../mosquitto/lib/mosquitto.h"  #define  STU_NAME_LEN  32  /* 学生结构体 */ typedef struct _Student {     char name[STU_NAME_LEN];  // 名字           int num;                  // 学号           int c_score;              // C语言分数 }StudentDef, *pStudentDef;  /* 内部函数声明 */ static void StudentsData_Parse(pStudentDef _Stu, const char *_JsonStudnetData); static void PrintParseResult(const pStudentDef _Stu); static void SaveParseResult(const pStudentDef _Stu); static void my_message_callback(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *message); static void my_connect_callback(struct mosquitto *mosq, void *userdata, int result);  /* 内部全局变量 */ static FILE *stu_fp = NULL;  /******************************************************************************************************** ** 函数: main **------------------------------------------------------------------------------------------------------ ** 参数:  ** 说明:  ** 返回:  ********************************************************************************************************/ bool clean_session = true; int main(void) {              struct mosquitto *mosq = NULL;      /* libmosquitto 库初始化 */     mosquitto_lib_init();      /* 创建mosquitto客户端 */     mosq = mosquitto_new(NULL, clean_session, NULL);     if(NULL == mosq)     {         printf("Create mqtt client failed... ");         mosquitto_lib_cleanup();         return 1;     }      /* 绑定连接、消息接收回调函数 */     mosquitto_connect_callback_set(mosq, my_connect_callback);     mosquitto_message_callback_set(mosq, my_message_callback);      /* 连接服务器 */     if(mosquitto_connect(mosq, "localhost", 1883, 60))     {         printf("Unable to connect... ");         return 1;     }      /* 循环处理网络消息 */     mosquitto_loop_forever(mosq, -1, 1);      /* 回收操作 */     mosquitto_destroy(mosq);     mosquitto_lib_cleanup();      return 0; }  /******************************************************************************************************** ** 函数: StudentsData_Parse, JOSN格式学生期末数据解析 **------------------------------------------------------------------------------------------------------ ** 参数: _JsonStudnetData:JSON数据   _Stu:保存解析出的有用数据 ** 说明:  ** 返回:  ********************************************************************************************************/ static void StudentsData_Parse(pStudentDef _Stu, const char *_JsonStudnetData) {     cJSON *student_json = NULL;   // student_json操作对象,可代表 {} 扩起来的内容     cJSON *name = NULL;                  cJSON *num = NULL;     cJSON *c_score = NULL;          /* 开始解析 */     student_json = cJSON_Parse(_JsonStudnetData);     if (NULL == student_json)     {         const char *error_ptr = cJSON_GetErrorPtr();         if (error_ptr != NULL)         {             fprintf(stderr, "Error before: %s ", error_ptr);         }         goto end;     }      /* 解析获取name得值 */     name = cJSON_GetObjectItemCaseSensitive(student_json, "name");     if (cJSON_IsString(name) && (name->valuestring != NULL))     {         memset(&_Stu->name, 0, STU_NAME_LEN*sizeof(char));         memcpy(&_Stu->name, name->valuestring, strlen(name->valuestring));     }      /* 解析获取num的值 */     num = cJSON_GetObjectItemCaseSensitive(student_json, "num");     if (cJSON_IsNumber(num))     {         _Stu->num = num->valueint;     }      /* 解析获取c_score的值 */     c_score = cJSON_GetObjectItemCaseSensitive(student_json, "c_score");     if (cJSON_IsNumber(c_score))     {         _Stu->c_score = c_score->valueint;     }  end:     cJSON_Delete(student_json); }  /******************************************************************************************************** ** 函数: PrintParseResult, 打印输出解析结果 **------------------------------------------------------------------------------------------------------ ** 参数:  ** 说明:  ** 返回:  ********************************************************************************************************/ static void PrintParseResult(const pStudentDef _Stu) {     printf("name: %s, num: %d, c_score: %d  ", _Stu->name, _Stu->num, _Stu->c_score); }  /******************************************************************************************************** ** 函数: SaveParseResult, 保存解析结果 **------------------------------------------------------------------------------------------------------ ** 参数: _Stu:需要保存的数据 ** 说明:  ** 返回:  ********************************************************************************************************/ static void SaveParseResult(const pStudentDef _Stu) {     char write_buf[512] = {0};     static int stu_count = 0;      /* 以可在文件末尾追加内容的方式打开文件 */     if((stu_fp = fopen("ParseResult.txt", "a+")) == NULL)     {         printf("Open file error! ");         return exit(EXIT_FAILURE);     }       /* 按指定格式写入文件 */     snprintf(write_buf, 512, "name: %s, num: %d, c_score: %d ", _Stu->name, _Stu->num, _Stu->c_score);     size_t len = fwrite((char*)write_buf, 1, strlen(write_buf), stu_fp);      /* 文件位置指针偏移 */     fseek(stu_fp, len * stu_count, SEEK_SET);     stu_count++;      /* 关闭文件 */     fclose(stu_fp); }  /******************************************************************************************************** ** 函数: my_message_callback, 消息接收回调函数 **------------------------------------------------------------------------------------------------------ ** 参数:  ** 返回:  ********************************************************************************************************/ static void my_message_callback(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *message) {     StudentDef stu = {0};      if(message->payloadlen)     {         printf("%s %s ", message->topic, (char*)message->payload);          /* 解析JSON数据 */         StudentsData_Parse(&stu, (const char*)message->payload);            /* 打印输出解析结果 */         PrintParseResult(&stu);            /* 保存数据到文件 */         SaveParseResult(&stu);      }     else     {         printf("%s (null) ", message->topic);     }     fflush(stdout); }  /******************************************************************************************************** ** 函数: my_connect_callback, 连接回调函数 **------------------------------------------------------------------------------------------------------ ** 参数:  ** 返回:  ********************************************************************************************************/ static void my_connect_callback(struct mosquitto *mosq, void *userdata, int result) {     if(!result)     {         /* 订阅test_topic主题的消息 */         mosquitto_subscribe(mosq, NULL, "test_topic", 0);     }     else     {         fprintf(stderr, "Connect failed ");     } }编译运行
  1、编译生成json_parse、json_print程序:gcc cJSON.c json_parse.c -L ../mosquitto/build/lib -lmosquitto -o json_parse gcc cJSON.c json_print.c -L ../mosquitto/build/lib -lmosquitto -o json_print    
  这里用到链接动态库的方式生成可执行程序。关于动态链接与静态链接,可查看往期笔记:静态链接与动态链接(Linux) 、静态链接与动态链接 。
  2、执行json_parse、json_print程序:
  执行这两个程序会报错:
  ./json_parse: error while loading shared libraries: libmosquitto.so.1: cannot open shared object file: No such file or directory /json_print: error while loading shared libraries: libmosquitto.so.1: cannot open shared object file: No such file or directory
  这是因为 不能找到共享库文件libmosquitto.so.1 ,加载失败。
  因为一般情况下Linux会在/usr/lib 路径中搜索需要用到的库,而libmosquitto.so.1 库并不在这个路径下。
  解决方法有两种:一种就是把这个文件拷贝至/usr/lib 路径下,但是一般不允许这样做,一般用户也不允许往这个路径里拷贝东西。另一种就是把libmosquitto.so.1 库所在路径增加为动态库的搜索路径,命令为:export LD_LIBRARY_PATH=../mosquitto/build/lib:$LD_LIBRARY_PATH
  关于这方面的说明可以阅读往期笔记:静态链接与动态链接(Linux)
  按照上述方法添加动态库搜索路径之后就可以正常运行这两个程序:
  ParseResult.txt文本里得到:
  实验成功!
  以上就是本次的分享,代码写得比较仓促,如有错误,麻烦指出,谢谢!由于准备demo花了挺多时间,包括注释也写了很多。所以本篇文章就不做过多的说明,感兴趣的朋友可以结合本篇文章的demo及mosquitto/client/pub_client.c 、mosquitto/client/sub_client.c 这两个源文件。
  本篇文章的demo:
  由于篇幅有限。代码可在私信回复关键词:json_mqtt_demo ,即可获取。
  1024G 嵌入式资源大放送!包括但不限于C/C++、单片机、Linux等。私信回复 1024,即可免费获取!

谷歌宣布推出自研智能手机芯片据日经中文网8月3日报道,谷歌将扩大自研半导体的应用。谷歌开发了智能手机半导体,将配备在年内上市的两款旗舰机型上。该半导体提高了处理图像和声音的人工智能(AI)水平。报道称,谷歌在续航600km的电动SUV不到14万,埃安AIONY值吗?对于想买电动车的消费者来说,电池安全和续航方面想必是大家最关心的问题。再年轻点的消费者,可能对价格颜值有要求。今天给大家推荐一款各方面表现还不错的电动SUV,它就是广汽埃安AION迸发Ace力!哈氪觉醒真无线运动耳机体验夏日运动行动派练起来前言距离2020东京奥运会闭幕式已经剩下不到一周的时间了,我们的奥运健儿们也是迸发Ace力了,稳居金牌榜第一,已经获得29块的金牌了,同时奖牌总数距离美国也只差三块了,照这种趋势下七夕送礼必备好物高颜值高性价比的蓝牙耳机随着蓝牙技术的高速发展,蓝牙耳机的热度逐渐开始超越有线耳机了,已经成为了主流的耳机类型。由于没了耳机线的束缚,听歌看剧时就更加自由,可以无拘无束地享受美妙音乐,在这里就分享几款高颜iOS14。7验证通道关闭,iOS15新功能上线了文机sir相信有一直关注机sir至今的果粉们应该都知道了,对于智能手机来说其最大的特点是可以升级更新系统获得最新的功能跟体验,说起来在系统升级更新方面,苹果的iOS系统还是比较积极试听评测性价比卓越的平板振膜耳机金平面GL2000近年来,国产品牌在各行各业都展现出了相当的实力,不让进口品牌专美,而且凭借出色的性价比让更多的消费者获得了实在的好处。在音频领域也不例外,耳机圈里最红火平板振膜领域,除了此前规模和今年七夕送什么礼物好?推荐几款很适合送礼的运动耳机在七夕等节日的时候,带着你的恋人,牵手看朝阳看日落,只要两个人在一起,一切都是如此的美好。另外,不要忘记准备一份礼物哦,那么今年七夕送什么礼物好呢?我们都知道在提倡全民运动的如今,性能强悍,超高屏幕刷新率,很适合游戏爱好者哈喽大家好,我是你们的老朋友小生,每天都会给大家更新我的原创内容,今年黑鲨又发布了一款超强的电竞旗舰,也就是目前口碑很好的黑鲨4Pro。游戏手机针对游戏方面非常的专业,黑鲨4Pro六大要点别踩坑什么人适合购买激光电视都说土豪才能适合购买激光电视,其实这不仅仅是钱的事情,购买之前,还有些问题你得考虑清楚。今天就剪短扼要地给大家说清楚第一,你得有钱,毕竟入门激光都要一万多,好点的三四万,没钱还是买谷歌地图又有新发现,被地雷围绕的沙漠中有一片秘密军事基地近日,一位眼尖的谷歌地图用户在被地雷包围的撒哈拉沙漠中央发现了一个秘密军事基地。从谷歌地球上拍摄的空中图像显示,该设施位于靠近利比亚边境的尼日尔。一位用户在Reddit上分享了这一7月应用排行榜淘特一鸣惊人,抖音被小老弟打败7月应用榜单新鲜出炉,让我们一起来看看7月中国区AppStore应用市场又有哪些变化?在一众老牌强者的包围中是否会有后起之秀一鸣惊人呢?往下看!7月热门应用下载Top30在7月份应
周小川三不为数字人民币正名随着场景的逐步铺开和试点的不断深入,如今,数字人民币引发越来越多的讨论究竟数字人民币如何实现可控匿名?是否会取代微信支付宝等第三方支付?又将如何推动人民币国际化?率先落地哪些场景?美国加州公司研发无人驾驶帆船应对地球气候变化威胁气候变化正在重塑地球,导致海平面上升,北极冰融化,全球气温升高。根据NASA的数据,全球平均海平面在过去100年里上升了7英寸。北极夏季海冰已经缩减到有记录以来的最低水平,自2002000价位5G手机性能排名榜首15GB256GB,高通骁龙870,66W快充随着华为P50,以及荣耀50系列发布会越来越近,整个手机市场将呈现两种节奏。第一个节奏就是,华为P50仍然采用麒麟9000芯片,但是供货量会相对进一步减少,第二个节奏是荣耀搭载了高微信双开太简单了!学会这几种方法,就能同时登录2个微信分享最实在的玩机技巧,洞察最前沿的科技资讯!大家好,这里是手机科技园!我们在生活中,几乎每天都会用到微信,但是一台设备只能登录一个微信,如果你想登录多个微信号,该怎么办呢?今天就来造车不如卖电池!蔚来等还在排队为他打工,他已当上香港首富文华商韬略七月他不仅让李嘉诚让位,还让一众企业家排队为他打工。他把一生都当做赌局,却能逢赌必赢。他就是曾毓群。2011年曾毓群创办宁德时代,仅用十年,市值就达到了8500多亿。曾毓宁要曹县一张床,不要北京一套房。爆火的曹县到底什么来头?近日,曹县梗在网络上迅速走红。5月17日,曹县县长针对曹县走红作出回应欢迎各位到北上广曹中的曹县来看一看,看看真实的曹县。这句话很凡尔赛,也说明了曹县如今确实也成为了现象级的网红城行为堪比辣笔小球!多人侮辱袁隆平院士被抓,互联网岂是法外之地5月22日,是一个悲伤的日子,这一天,袁隆平院士永远离开了我们。大家纷纷在社交媒体上发文悼念袁老先生时,却有人倒行逆施,发文污蔑辱骂他。天津一网友在朋友圈发表了侮辱性言论,造成了恶当今时代想要做好电商,必须要了解以下几点,助你互联网思维突破哈喽大家好,我是云众秋风,一个90后电商创业者,今天给大家分享一下如何突破电商思维,帮助你做互联网走的更远!在当今的时代,如果想要做好电商,必须要了解以下几点,绝大多数电商的人都还5000人加入小米,入职小米到底是怎样的体验?2021年校招训练,在小米北京总部已经举行,看起来现场还是蛮有气氛的,雷军和许多小米高管都出席了现场,同时在这次训练会中,雷军还亲自表示希望看到30岁集团高管的出现,雷军始终保持一华为注册麒麟处理器商标曝内部正研发3nm芯片麒麟9010近两年华为在先进的科技领域发展迅速,尤其是在5G技术方面已经领先全球。这也让美国十分忌惮,所以美国以国家安全为由将华为列入实体清单,禁止使用美国技术或者设备的公司为华为提供芯片等。多家机器人公司跌落神坛文大峻2021年转眼已快过半,中国工业机器人行业经历近十几年的发展,已经从最初的追赶变成如今的蓬勃竞艳,整体规模逐年上涨,且连续多年成为全球最大的市场,但风口时代早已过去,曾经风云