上一篇文章已经将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

#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 $< -o $@ $(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)

四、测试

  1. 在虚拟机上打开代理服务器,并将编译生成的mqtt_sub_demo和mqtt_pub_demo移动到ARM开发版上

  2. 打开mqqt订阅者

  3. 打开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

使用Mosquitto实现MQTT客服端C语言的更多相关文章

  1. TCP服务器端和客服端(一)

    就是一个客服端(Socket)和服务器(ServerSocket)端的链接间.我的理解是一个服务端可以链接多个客服端. 在客服端有输入流outPutStream. 用于发送数据 在服务器端有输出流.i ...

  2. Live555 分析(三):客服端

    live555的客服端流程:建立任务计划对象--建立环境对象--处理用户输入的参数(RTSP地址)--创建RTSPClient实例--发出DESCRIBE--发出SETUP--发出PLAY--进入Lo ...

  3. mvc 防止客服端多次提交

    但凡web开发中都会有户多次点击了提交按钮导致多次提交的情况,一般的集中做法 1.通过js在用户点击的时候将按钮disabled掉,但是这样并不是很可靠(我就可以跳过这个,用一个for循环 我直接自己 ...

  4. 浏览器与服务器间的交互(客服端 <---> 服务器)

    浏览器与服务器间的交互(客服端 <---> 服务器) 请求--->处理--->响应 对类HttpContext 内部成员的使用 例如 :Request .Response .  ...

  5. Spring Cloud 客服端负载均衡 Ribbon

    一.简介   Spring Cloud Ribbon 是一个基于Http和TCP的客服端负载均衡工具,它是基于Netflix Ribbon实现的.它不像服务注册中心.配置中心.API网关那样独立部署, ...

  6. 四:客服端防护HTTP发送请求类

    一.源代码: public class swtDefendOperate{private BackgroundWorker backgroundWorker;//DefendType的值 Verify ...

  7. android客服端+eps8266+单片机+路由器之远程控制系统

    用android客服端+eps8266+单片机+路由器做了一个远程控制的系统,因为自己是在实验室里,所以把实验室的门,灯做成了远程控制的. 控制距离有多远------只能说很远很远,只要你手机能上网的 ...

  8. jetty 客服端 与服务端

    jetty 服务端,客服端有请求buffter 检查 默认4kb 4096 客服端 HttpClient client=new HttpClient(); client.setRequestBuffe ...

  9. python服务器端、客户端的模型,客服端发送请求,服务端进行响应(web.py)

    服务器端.客户端的模型,客服端发送的请求,服务端的响应 相当于启动了一个web server install web.py 接口框架用到的包 http://webpy.org/tutorial3.zh ...

随机推荐

  1. 类加载机制+JVM调优实战+代码优化

    类加载机制 Java源代码经过编译器编译成字节码之后,最终都需要加载到虚拟机之后才能运行.虚拟机把描述类的数据从 Class 文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直 ...

  2. ThinkPHP 5

    use think\Controller 1.$this->request->param();      内置request 安全对象, 不再使用 $_GET ,$_POST 2.path ...

  3. Docker安装Kong API Gateway并使用

    我最新最全的文章都在南瓜慢说 www.pkslow.com,文章更新也只在官网,欢迎大家来喝茶~~ 1 简介 Kong不是一个简单的产品,本文讲的Kong主要指的是Kong API Gateway,即 ...

  4. MSTP

    目录 一.生成树存在的问题 二.MSTP 三.MSTP的网络层次 四.MSTP的端口状态 五.MSTP的保护功能 一.生成树存在的问题 STP和RSTP的问题 PVST的问题 二.MSTP 多生成树 ...

  5. ssrf漏洞随笔

    一.ssrf漏洞定义 SSRF漏洞:SSRF是一 种由攻击者构造请求,由服务端发起请求的安全漏洞.一般情况下,ssrf攻击的目标是外网无法访问的内部系统 SSRF漏洞( 服务器端请求伪造 )也被称为跨 ...

  6. 字节跳动、快手等大厂Android面试刨根问底之内存泄露篇

    现在快手字节跳动等公司都在大量招人,薪资优厚,但是想进去却没那么简单,面过的人都知道,这些公司的面试官巴不得把你会的东西都给你挖出来,所以要深入复习知识点,让自己耐问一点.一下是针对内存泄露真实面试过 ...

  7. 十六进制转十进制 BASIC-12

    十六进制转十进制 代码 import java.math.BigInteger; import java.util.Scanner; /* * 从键盘输入一个不超过8位的正的十六进制数字符串, * 将 ...

  8. 进程之间的通信(multiprocess.Queue)

    一.进程间通信 进程之间的数据是相互隔离的,例如 from multiprocessing import Process def task(): global n # 声明全局变量 n = 999 p ...

  9. SQL 练习12

    查询和" 01 "号的同学学习的课程 完全相同的其他同学的信息 分析 如果某同学学的某一个课程和01同学所学的课程有对应,那么子查询返回false. 如果没有对应,子查询返回tru ...

  10. C#中的几种锁:用户模式锁、内核模式锁、动态计数、监视锁

    参考网址: https://blog.csdn.net/weixin_43989331/article/details/105356008 C#中的几种锁:用户模式锁.内核模式锁.动态计数.监视锁介绍 ...