MQTT 和 mosquitto 编程和移植
知识点1:MQTT概述
概念:
Message Queuing TelemetryTransport,消息队列遥测传输。
特点:
1、针对移动终端设备的基于TCP/IP的发布/订阅协议
2、可以保持长连接,具有一定的实时性,广泛应用物联网嵌入式中。
3、是基于TCP的应用层协议,要一直保持连接,功耗高。
4、使用发布/订阅消息模式,提供一对多的消息 发布,解除应用程序耦合。
5、三种消息发布服务质量(QoS):(记!)
Ø“至多一次” ,(Qos0)消息发布完全依赖底层 TCP/IP 网络,会发生消息丢失或重复,这一级别可用于 对采集数据要求不严格的情况
Ø“至少一次” ,(Qos1)确保消息到达,但消息可能会重 复发生
Ø“只有一次” ,(Qos2)确保消息只到达一次,这一级别 可用于要求严格如涉及计费系统的情况,消息重 复或丢失都是不允许的
6、允许用户动态创建主题,零运维成本
7、数据不可知,不强求传输数据的类型与格式,保持灵活性
8、低带宽、高延迟、不稳定的网络等因素考虑在内
9、cs架构
替代了传统的客户端/服务器模型,可以实现以下解耦:
空间解耦,发布者和订阅者不需要知道对方
时间解耦,发布者和订阅者不需要同时运行(离线消息)
同步解耦,发布和接收都是异步通讯,无需停止任何处理
知识点2:MQTT协议介绍(了解)
1、固定控制报头
2、剩余数据长度
3、可变长度报头
4、有效数据载荷(真实数据)
知识点3:mosquitto移植
mosquitto是一个高质量轻量级的开源MQTT broker,目前支持MQTTv3.1和v3.1.1协议,
1、同时提供了一个C语言动态链接库libmosquitto
2、mosquitto由MQTT协议创始人之一的AndyStanford-Clark参与开发
安装及使用(linux/x86):
1、命令安装(优先选用)
安装:(重要!!!)
sudo apt-get install mosquitto
sudo apt-get install mosquitto-clients
使用:(重要!!!)
//往10.9.29.124服务器发布主题是"bj2401"的hello消息
mosquitto_pub -h 10.9.29.124 -t "bj2401" -m "hello"
//从10.9.29.124服务器订阅主题是"bj2401"的消息
mosquitto_sub -h 10.9.29.124 -t "bj2401"
注意:如果连接被拒绝,修改配置文件(/etc/mosquitto/mosquitto.conf),增加四行信息。
1、打开配置文件
sudo gedit /etc/mosquitto/mosquitto.conf
2、增加如下内容:
allow_anonymous true
listener 1883 0.0.0.0
socket_domain ipv4
protocol mqtt
3、重启服务
sudo systemctl restart mosquitto
2、源码安装(了解)
步骤1:安装依赖库openssl
步骤2:安装依赖库libuuid
步骤3:安装mosquitto
安装及使用(linux/arm):
1、源码安装(只能选用)
安装:(了解)
参考《linux(开发板)移植》
使用:(重要!!!)
步骤1:找到压缩包并在虚拟机解压
tar xvf mqtt_arm.tar.bz2
步骤2:将生成的服务器及客户端映射到开发板
步骤3:开发板启动服务器
./mosquitto
3.1如果报错:
解决方法:
先找到缺少的库的路径,然后增加到环境变量LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/缺少的库的路径
解决方法:
echo "user root" > user.conf
./mosquitto -c user.conf -v
步骤4:测试开发板上的服务器
./mosquitto -c user.conf -v
步骤4:测试开发板上客户端
linux(开发板)移植:(了解)
步骤1:安装mosquitto的依赖包openssl
1.1找到源码包,下载到虚拟机,解压
1.2新建文件夹保存arm版本的opessl的库及头文件
mkdir openssl_arm
1.3配置编译安装
cd openssl-1.0.1e
./config --prefix=/home/edu/.../openssl_arm
//修改makefile脚本看下图
make
make install
步骤2:安装mosquitto的依赖包libuuid
1.1找到源码包,下载到虚拟机,解压
1.2新建文6版本的libuuid的库及头文件
mkdir libuuid_arm
1.3配置编译安装
cd libuuid-1.0.3
./configure --host=arm-linux CC=arm-linux-gcc --prefix=/home/edu/bj2303/mqtt/libuuid_arm
make
make install
步骤3:安装mosquitto
3.1找到源码包,下载到虚拟机,解压
3.2新建文件夹保存arm版本的mosquitto的库及头文件、服务器、客户端
mkdir mosquitto_arm
3.3配置
配置打开配置文件修改gedit config.mk
//行16:
CC=arm-linux-gcc
CXX=arm-linux-g++
prefix=/home/edu/bj2303/mqtt/mosquitto_arm
//133行
CFLAGS:=-I/home/edu/bj2303/mqtt/openssl_arm/include -I/home/edu/bj2303/mqtt/uuid_arm/include
LDFLAGS=-L/home/edu/bj2303/mqtt/openssl_arm/lib -lm -ldl -lssl -lcrypto -L/home/edu/bj2303/mqtt/uuid_arm/lib -luuid
-lrt
//148行
BROKER_LIBS =-L/home/edu/bj2303/mqtt/openssl_arm/lib -lm -ldl -lssl -lcrypto -L/home/edu/bj2303/mqtt/uuid_arm/lib -luuid
PASSWD_LIBS =-L/home/edu/bj2303/mqtt/openssl_arm/lib -lssl -lcrypto
LIB_LIBS =-L/home/edu/bj2303/mqtt/openssl_arm/lib -lssl -lcrypto
//206行
BROKER_LIBS =-L/home/edu/bj2303/mqtt/openssl_arm/lib -lm -ldl -lssl -lcrypto -L/home/edu/bj2303/mqtt/uuid_arm/lib -luuid
PASSWD_LIBS =-L/home/edu/bj2303/mqtt/openssl_arm/lib -lssl -lcrypto
LIB_LIBS =-L/home/edu/bj2303/mqtt/openssl_arm/lib -lssl -lcrypto
3.4编译安装
make
sudo make install
知识点4:mosquitto编程(重要)
常用函数:
https://mosquitto.org/api/files/mosquitto-h.html
发布客户端:
1、初始化
2、创建客户端
3、连接服务器
4、发布
5、销毁客户端
6、反初始化
#include <stdio.h>
#include <string.h>
#include <mosquitto.h>
int main(){
//1、初始化
mosquitto_lib_init();
//2、创建客户端
struct mosquitto *pub_client = mosquitto_new("pub",false,NULL);
if(pub_client==NULL){
printf("创建客户端失败");
return -1;
}
//3、连接服务器
int ret = mosquitto_connect(pub_client,"10.9.29.124",1883,6);
if(ret != MOSQ_ERR_SUCCESS){
printf("连接服务器失败");
return -1;
}
//4、发布
int mid=1;
mosquitto_publish(pub_client,&mid,"bj2401",strlen("helloo"),"helloo",1,false);
//5、销毁客户端
mosquitto_destroy(pub_client);
//6、反初始化
mosquitto_lib_cleanup();
return 0;
}
另一种实现:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
system("mosquitto_pub -h 10.9.29.49 -t 'bj2401' -m 'hello' ");
return 0;
}
订阅客户端:
1、初始化
2、创建客户端
3、连接服务器
4、订阅函数
5、消息回调
6、主事件循环
7、销毁客户端
8、反初始化
#include <stdio.h>
#include <mosquitto.h>
#include <string.h>
//消息回调
void callback_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message){
printf("recv:%s\n",(char *)message->payload);
}
int main(){
//1、初始化
mosquitto_lib_init();
//2、创建客户端
struct mosquitto *sub_client = mosquitto_new("sub",false,NULL);
if(sub_client==NULL){
printf("创建客户端失败");
return -1;
}
//3、连接服务器
int ret = mosquitto_connect(sub_client,"10.9.29.49",1883,6);
if(ret != MOSQ_ERR_SUCCESS){
printf("连接服务器失败");
return -1;
}
//4、订阅函数
int mid=1;
mosquitto_subscribe(sub_client,&mid,"bj2401",1);
//5、消息回调
mosquitto_message_callback_set(sub_client,callback_message);
//6、主事件循环
mosquitto_loop_start(sub_client);
mosquitto_loop_stop(sub_client,false);
//7、销毁客户端
mosquitto_destroy(sub_client);
//8、反初始化
mosquitto_lib_cleanup();
return 0;
}
另一种写法:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
int main(){
int fd[2];
pipe(fd);//创建无名管道
pid_t pid=fork();
if(pid<0)
return -1;
else if(pid==0){//子进程使用无名管道的写端,将其标准输出写到管道
close(fd[0]);
dup2(fd[1],1);
system("mosquitto_sub -h 10.9.29.49 -t 'bj2401' ");
}else{ //父进程读管道的读端,拿到订阅的消息,进行处理
close(fd[1]);
char buf[128]="";
//订阅到的数据进程处理
while(1)
{
bzero(buf,sizeof(buf));
read(fd[0],buf,sizeof(buf));
printf("recv:%s\n",buf);
}
}
return 0;
}
推荐阅读
-
Golang 并发编程入门:Goroutine 简介和基本用法
-
动态编程 - 子阵列系列 - 最大子阵列和
-
基于 SSM+Vue+MySQL 的儿童编程在线报名系统 - 目的和意义
-
MQTT 和 mosquitto 编程和移植
-
[C++ 核心编程] 注释 4.1.2 结构和类的区别
-
力扣 1884.Egg Drop Two Egg(两个鸡蛋掉落) - 输入: n = 100 输出: 1414 解说 最佳策略是 - 从 9 楼扔下第一个鸡蛋。如果蛋碎了,那么 f 在 0 和 8 之间。从第 1 层扔第 2 个鸡蛋,然后每扔 1 层,分 8 次找到 f。总操作次数 = 1 + 8 = 9。 - 如果第一个鸡蛋没有破,那么从 22 楼扔第一个鸡蛋。如果蛋碎了,那么 f 介于 9 和 21 之间。将第二个鸡蛋从 10 楼往下扔,然后每扔一次往上扔一层楼,在 12 次尝试中找出 f。总操作次数 = 2 + 12 = 14。 - 如果第一个鸡蛋没有再次破碎,那么用类似的方法从 34、45、55、64、72、79、85、90、94、97、99 和 100 层扔第一个鸡蛋。 无论结果如何,最多需要扔 14 次才能确定 f。 一个非常有趣的问题 方法 1:动态编程
-
汇编语言]寄存器(CPU 如何工作)(VII) - 查看 CPU 和内存,使用机器指令和汇编指令编程 - 结论
-
[C++ 核心编程] 注意事项 2 堆栈和堆区 - 堆区:
-
C# Ecosystem] 突破异步编程挑战:深入分析面向 .NET Framework 的异步工具和库
-
[ECMAScript 从入门到进阶教程] 第三部分:高级主题(高级函数和范例、元编程、正则表达式、性能优化)