前言
**
相关简介:
MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议,是一种基于发布/订阅 (publish/subscribe)模式的轻量级协议,该协议构建于 TCP/IP 协议之上, MQTT 最大优点在于,可以以 极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。作为一种低开销、低带宽占用的即 时通讯协议,使其在物联网、小型设备、移动应用等方面有较广泛的应用。
完成目标:
1,完成mosquitto库的编译
2,编写基于mosquitto的程序
3,编译,烧录和运行
一、libuuid库的编译
libuuid库下载:https://sourceforge.net/projects/libuuid/
最新版本为1.0.3,更新于2013年4月27日,此库仅支持在类Linux下编译使用。UUID来源于OSF(Open Software Foundation,开源软件基金会)的DCE(Distributed Computing Environment,分布式计算环境)规范,UUID是指在一台机器上生成的数字,保证在全球范围的唯一性,这里的mqtt的id需要确保唯一性,如果用户没有设置id链接mqtt的时候会主动调用该库生成id。
tar -vxf libuuid-1.0.3.tar.gz # 创建一个存放编译后的文件目录 mkdir -p /opt/mosquitto-arm cd libuuid-1.0.3 ./configure --prefix=/opt/mosquitto-arm/libuuid-1.0.3 CC=arm-linux-gcc --host=arm-linux make make install
二、openssl库的编译
openssl库下载:https://www.openssl.org/source/old/1.0.2/
openssl是一个功能丰富且自包含的开源安全工具箱。它提供的主要功能有:SSL协议实现(包括SSLv2、SSLv3和TLSv1)、大量软算法(对称/非对称/摘要)、大数运算、非对称算法密钥生成、ASN.1编解码库、证书请求(PKCS10)编解码、数字证书编解码、CRL编解码、OCSP协议、数字证书验证、PKCS7标准实现和PKCS12个人数字证书格式实现等功能。
openssl采用C语言作为开发语言,这使得它具有优秀的跨平台性能。openssl支持Linux、UNIX、windows、Mac等平台。
tar -vxf openssl-1.0.2e.tar.gz cd openssl-1.0.2e # 配置编译参数 setarch i386 ./config no-asm shared --prefix=/opt/mosquitto-arm/openssl/
- setarch i386:声明生成的是 32 位 CPU,如果是 64 位 CPU 则去除该部分
- –prefix :指定 make install 后生成目录的路径,不修改此项则默认为 OPENSSLDIR 目录 (/usr/local/ssl)。
- shared :生成动态连接库。
- no-asm:是在交叉编译过程中不使用汇编代码代码加速编译过程,原因是它的汇编代码 是对 arm 格式不支持的如果
修改生成的Makefile文件中的编译器
CC= arm-linux-gcc AR= arm-linux-ar $(ARFLAGS) r RANLIB= arm-linux-gcc-ranlib NM= arm-linux-gcc-nm
执行编译安装
make make install
三、mosquitto库的编译
mosquitto下载地址:https://mosquitto.org/files/source/
Mosquitto 是 MQTT 的实现方法,因为 MQTT 是一种协议,就好比 Linux 和 Ubuntu 的关系。Ubuntu 是 Linux 的发行版之一,而 Mosquitto 是 MQTT 的实现方法之一,为什么我们的这里使用的是 Mosquitto 而不是其 他的实现方法呢,因为 Mosquitto 功能强大,不仅可以作为消息的发布者和订阅者,也可以做为服务器。其 他工具有的功能他基本都有,所以我们使用的是 Mosquitto。
这里根据自己下载的版本解压对应的源码
tar -xvf mosquitto-1.5.tar.gz cd mosquitto-1.5 # 这里需要注意的是libuuid库和openssl库的目录如果不是按照我这个前面一样的话需要根据自己的安装路径进行修改 make WITH_SRV=no CC=arm-linux-gcc CXX=arm-linux-g++ CFLAGS="-I /opt/mosquitto-arm/openssl/include -I /opt/mosquitto-arm/libuuid-1.0.3/include -I /opt/mosquitto-arm/openssl/lib -I /opt/mosquit/to-arm/libuuid-1.0.3/lib" LDFLAGS="-L /opt/mosquitto-arm/openssl/lib -L /opt/mosquitto-arm/libuuid-1.0.3/lib -lssl -lcrypto -luuid" make DESTDIR=/opt/mosquitto-arm/mosquitto-1.5 install
四、文件拷贝到开发板
我们在刚刚编译安装源码的地方创建一个arm文件夹
mkdir arm cp mosquitto-1.5/etc/mosquitto/mosquitto.conf.example ./arm/ cp mosquitto-1.5/usr/local/bin/* ./arm/ cp mosquitto-1.5/usr/local/sbin/mosquitto ./arm/ cp -rf libuuid-1.0.3/ mosquitto-1.5/ openssl/ ./arm/
然后我们将这个文件夹拷贝到nfs文件夹,开发板挂载nfs,开始将文件移植到开发板中
# 我们把开发板当前目录下 libuuid-1.0.3/ mosquitto-1.5/ openssl/三个文件下的 lib 下 的库全部 放到开发板的/lib 下面 cp -rf libuuid-1.0.3/lib/* mosquitto-1.5/usr/local/lib/* openssl/lib/* /lib/ cp mosquitto.conf.example /etc/mosquitto.conf cp mosquitto mosquitto_* /bin
运行服务测试
mosquitto -d -c /etc/mosquitto.conf # 根文件系统采用busybox构建使用ps指令参数只有w和l其余的跟文件系统参数为ef或者e就可以 ps -w |grep mosquitto
我这里使用我个人搭建的一个emqx的服务端进行测试
- 订阅主题:
mosquitto_sub -h 192.168.1.3 -t "mqtt"
-v 其中参数-h 是指定要连接的 MQTT 服务器,这里的 IP 为自己 服务端的 IP,
-t 订阅主题,此处为 mqtt,所以主题为 mqtt,
-v 打印更多的调试信息。
- 发布主题
mosquitto_pub -h 192.168.1.3 -t "test" -m "Hello MQTT"
-v 其中参数-h 是指定要连接的 MQTT 服务器,这里的 IP 为自己 服务端的 IP,
-t 发布主题,此处为 test,所以主题为 test,
-m 发布的信息,此处发布的消息为”Hello MQTT“
五、程序的编写运行
Makefile
.SUFFIXES : .x .o .c .s CC := arm-linux-gcc STRIP := arm-linux-strip TARGET = mqttapp SRCS := mqttapp.c LIBPATH = -I /opt/mosquitto-arm/mosquitto-1.5/usr/local/include/ LIBPATH += -L /opt/mosquitto-arm/mosquitto-1.5/usr/local/lib/ LIBPATH += -L /opt/mosquitto-arm/libuuid-1.0.3/lib/ LIBPATH += -L /opt/mosquitto-arm/openssl/lib/ LIBS = -lmosquitto -lssl -lcrypto -luuid -lpthread all: $(CC) $(SRCS) -o $(TARGET) $(LIBPATH) $(LIBS) $(STRIP) $(TARGET) clean: rm -f *.o rm -f *.x rm -f *.flat rm -f *.map rm -f temp rm -f *.img rm -f $(TARGET) rm -f *.gdb
mqttApp.c
#include <stdlib.h> #include <stdio.h> #include <pthread.h> #include <stdint.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> // mqtt #include "mosquitto.h" void on_message(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *msg) { static int revc_num = 0; printf("[%d]topic:%s msg_len:%d qos:%d \r\nmsg:%s\r\n\n",\ revc_num++, msg->topic, msg->payloadlen,msg->qos,(const char *)msg->payload); if(!strcmp(msg->topic,"root") && !strcmp((const char *)msg->payload, "exit")) { exit(0); } } struct mosquitto *mosq = NULL; void *mqtt_entry(void *arg) { // struct mosquitto *mosq = NULL; int rc; mosq = mosquitto_new(NULL, true, NULL); mosquitto_lib_init(); mosquitto_connect(mosq, "124.223.xx.xx",1883,60); mosquitto_message_callback_set(mosq, on_message); mosquitto_subscribe(mosq, NULL, "root", 2); // 订阅主题 mosquitto_subscribe(mosq, NULL, "mqtt", 2); while(1) { mosquitto_loop(mosq, 1000,1); mosquitto_publish(mosq, NULL, "mqtt_pub", sizeof("hello"),"hello",1,true);// 发布消息 usleep(1000); } mosquitto_lib_cleanup(); #if 0 rc = mosquitto_subscribe_callback( on_message, NULL, "mqtt", 2,// 主题和qos "124.223.xx.xx", 1883, // IP和端口 NULL, 60, true, // id:null表示随机生成、心跳、senssion标志 NULL, NULL, // username、password NULL, NULL); // 遗嘱主题、使用tls if(rc){ printf("Error: %s\n", mosquitto_strerror(rc)); } #endif } int main(int argc, char *argv[]) { pthread_t mqtt_thread; pthread_create(&mqtt_thread,NULL, mqtt_entry, NULL); pthread_join(mqtt_thread, NULL); return 0; } // 更多的用法可以去看一下mosquitto的代码,注释还是比较完善的,如果只需要用到mqtt的收发功能,直接修改上面这个框架就足够用了
最后
对于Linux开发的基本流程都是相同的,这个流程同样可以应用在其他Linux开发板子上使用。
mosquitto下载地址:https://mosquitto.org/files/source/
openssl库下载:https://www.openssl.org/source/old/1.0.2/
libuuid库下载:https://sourceforge.net/projects/libuuid/