05--MQTT物联网协议

news2025/4/23 3:28:10

一、MQTT的概念

MQTT 协议快速入门 2025:基础知识和实用教程 | EMQ

1.MQTT(Message Queuing Telemetry Transport)是一种轻量级、基于发布-订阅模式的消息传输协议,适用于资源受限的设备和低带宽、高延迟或不稳定的网络环境。它在物联网应用中广受欢迎,能够实现传感器、执行器和其它设备之间的高效通信。

2.订阅与发布规则

二、MQTT 代理服务器

三、Mosquitto 代理服务器

Eclipse Mosquitto 也是一款开源的 MQTT Broker,兼容 MQTT 协议的 5.0、3.1.1 和 3.1 版本。Mosquitto 体积小巧,既可以运行在低功耗的单板计算机上,也可以部署在企业级服务器上。它采用 C 语言编写,可以用 C 库实现 MQTT 客户端。它支持 Windows、Mac、Linux 和 Raspberry Pi 等多种平台,为每个平台提供了方便安装的二进制文件。最新版本还增加了一个认证和授权插件 “mosquitto-go-auth”,以及一个用于管理 Mosquitto 实例的 Web 用户界面。此外,它还提供了一个 PHP 包装器 “Mosquitto-PHP”,可以方便地在 PHP 中开发 MQTT 客户端。

Eclipse Mosquitto 官方网站

GitHub - eclipse-mosquitto/mosquitto: Eclipse Mosquitto - An open source MQTT broker github开源网站

Mosquitto 服务器安装

1.下载 openssl 加密库源码

Old 1.1.1 Releases | OpenSSL Library

2.下载cjson 源码

GitHub - DaveGamble/cJSON: Ultralightweight JSON parser in ANSI C

3.下载mosquitto 服务器

Index of /files/source/

4.配置&安装⭐⭐

将下载好文件放到一个自己知道的路径,然后用wsl打开解压到家目录。不要解压到共享文件里。

------- openssl加密库安装---------
tar  -xvf   openssl-1.1.1q.tar.gz   -C    ~/   #1.解压源码 
cd  ~/openssl-1.1.1q/                          #2.进入源码目录  
./config                                       #3.默认配置  
 make   test  -j12                             #4.编译测试代码与库文件
 sudo  make  install                           #5.安装  
 
 
 ------cjson库安装-------
  cp  cJSON-master.zip   ~/    #1.拷贝到家目录
  cd  ~/                       #2.进入家目录
  sudo apt install unzip       #3.安装解压工具 
  unzip  cJSON-master.zip      #4.解压json源码 
  cd  cJSON-master/            #5.进入json源码
  make                         #6.编译源码
  sudo  make install           #7.安装 
  
  
 -----安装mosquitto代理服务器-----
sudo  apt-get install   g++                     #1.安装g++编译器
tar  -xvf  mosquitto-2.0.9.tar.gz   -C   ~/     #2.解压到家目录  
cd  ~/mosquitto-2.0.9/                          #3.进入源码目录   
make                                            #4.编译  
sudo  make  install                             #5.安装 

tip💡如果cjson库或ssl 库安装失败    
cJSON - for client JSON output support. Disable with make WITH_CJSON=no Auto detected with CMake.
 make WITH_CJSON=no   #去掉cjson 
 
openssl (libssl-dev on Debian based systems) - disable with make WITH_TLS=no
 make WITH_TLS=no

测试成功如下

四、mosquitto 代理服务器使用

1、订阅与发布命令

 #拷贝库文件到系统库中 
  sudo  cp  /usr/local/lib/lib*   /lib
 
 #拷贝系统的配置文件 
 cp  /etc/mosquitto/mosquitto.conf.example   ./  //当前文件为自己写代码的文件里

2、修改端口

3、关闭防火墙

#开启代理服务器  尝试能不能行
 mosquitto  -c  ./mosquitto.conf.example
 
 #订阅主题   'test/topic' 
 mosquitto_sub -t 'test/topic' -v
 
 #发布消息   
 mosquitto_pub -t 'test/topic' -m 'hello world'

4、发布端函数接口

将官方大的代码拷贝到自己写代码的文件里边看官方代码边写自己的代码。

//1初始化MQTT库,在调用任何函数之前必须要调用该函数 
int mosquitto_lib_init(void);
返回值:MOSQ_ERR_SUCCESS - on success.

//2创建一个新的客户端
struct mosquitto *mosquitto_new(const char *id, bool clean_session, void *obj);
id:客户端ID,如何为NULL ,系统自动分配一个ID,且clean_session参数必须为 true 
clean_session:  true   代理服务器在客户端断开后会清除数据 
                false  代理服务器在客户端断开后会保留数据 
obj:传递给回调函数的参数  
返回值:成功   客户端对象地址      
      失败    NULL 

//3连接MQTT服务器 
int mosquitto_connect(struct mosquitto *mosq, const char *host, int port, int keepalive);
mosq:客户端对象  
host:服务器IP地址 
port:服务器端口号 👉1883 
keepalive:保持连续ping 包,设置一段时间后发送一个ping给服务器 
返回值: MOSQ_ERR_SUCCESS - on success.


//4启动网络线程,不断处理网络数据   
int mosquitto_loop_start(struct mosquitto *mosq);
mosq:客户端对象  
返回值: MOSQ_ERR_SUCCESS - on success.

//5⭐重点,难点 : 发布消息 
int mosquitto_publish(struct mosquitto *mosq, //客户端对象  
                     int *mid,  //消息ID ,设置为 NULL 即可
                     const char *topic, //👍发布的消息主题
                      int payloadlen,   //发布消息长度   between 0 and 268,435,455.
                       const void *payload, //发布的消息
                       int qos,  //👍消息质量  0 ,1 , 2
                       bool retain); //消息保留标记为  true 保留消息

qos 消息质量

MQTT(Message Queuing Telemetry Transport)协议定义了三种消息质量等级(QoS),以确保在不同场景下消息的可靠传输。
以下是三种QoS级别的详细说明:
1. QoS 0(At Most Once,最多一次)
特点:消息最多被传递一次,没有确认机制,消息可能会丢失或重复。
适用场景:适用于对消息完整性要求不高的场景,如天气更新、实时数据流、传感器数据等。在这些场景中,即使消息丢失或重复,也不会造成重大影响。
传输过程:发送方发送消息后,不等待接收方的确认,也不存储消息以进行重传。
2. QoS 1(At Least Once,至少一次)
特点:消息至少被传递一次,但可能会出现重复的消息。
适用场景:适用于对消息丢失敏感,但对重复不敏感的场景,如传感器数据、开关状态同步等。在这些场景中,确保消息到达比避免重复更重要。
传输过程:发送方发送消息后,会等待接收方的确认报文(PUBACK)。如果未收到确认,发送方会重传消息。接收方收到消息后,会发送PUBACK确认报文。
3. QoS 2(Exactly Once,仅一次)
特点:消息确保只传递一次,没有重复。这是最高级别的QoS,适用于对消息的完整性和顺序性要求非常高的场景。
适用场景:适用于金融交易、关键命令等场景,在这些场景中,消息的丢失或重复都是不可接受的。
传输过程:发送方和接收方通过四次握手过程(PUBREC、PUBREL、PUBCOMP)来确保消息只被接收一次。发送方发送消息后,等待接收方的PUBREC确认,然后发送PUBREL,最后等待接收方的PUBCOMP确认。
QoS级别的选择
QoS 0:适用于实时性要求高,但对数据丢失和重复容忍度较高的场景。
QoS 1:适用于需要确保消息至少被接收一次,但允许重复的场景。
QoS 2:适用于需要确保消息仅被接收一次,且对实时性要求不高的场景。
注意事项
网络条件:在网络条件较差的情况下,建议选择较低的QoS级别,以减少消息丢失的风险。
系统资源:QoS级别越高,传输过程的复杂程度和系统资源消耗也越大。
综上所述,根据具体的应用场景和需求选择合适的QoS级别,可以在确保消息可靠传输的同时,优化系统性能和资源利用率。

⭐⭐发布端代码例子:

#include <mosquitto.h> //⚠️声明MQTT库的接口
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char *argv[])
{

    // 1.初始化MQTT库
    mosquitto_lib_init();

    // 2.创建一个客户端
    struct mosquitto *mosq = mosquitto_new(NULL, true, NULL);
    if (mosq == NULL)
    {
        perror("创建客户端失败\n");
        return 1;
    }
    else
    {
        printf("创建客户成功\n");
    }

    // 3.连接服务器,超时设置为60秒
    int ret = mosquitto_connect(mosq, "127.0.0.1", 1883, 60);
    if (ret != MOSQ_ERR_SUCCESS)
    {
        perror("连接服务器失败\n");
        return 1;
    }
    else
    {
        printf("连接服务器成功\n");
    }

    // 4.启动网络线程
    mosquitto_loop_start(mosq);

    while (1)
    {
        printf("请输入发布的主题和消息\n");
        char topic[50] = {0};
        char payload[268] = {0};
        scanf("%s %s", topic, payload);

        int ret = mosquitto_publish(mosq, NULL, topic, strlen(payload), payload, 0, false);
        if (ret != MOSQ_ERR_SUCCESS)
        {
            perror("发布消息失败\n");
            return 1;
        }
        else
        {
            printf("发布消息成功\n");
        }
    }
    
    mosquitto_destroy(mosq); //销毁对象
    mosquitto_lib_cleanup(); //清空函数库 
}

5、订阅端函数接口

//1.初始化MQTT库,在调用任何函数之前必须要调用该函数 
int mosquitto_lib_init(void);
返回值:MOSQ_ERR_SUCCESS - on success.

//2。创建一个新的客户端
struct mosquitto *mosquitto_new(const char *id, bool clean_session, void *obj);
id:客户端ID,如何为NULL ,系统自动分配一个ID,且clean_session参数必须为 true 
clean_session:  true   代理服务器在客户端断开后会清除数据 
                false  代理服务器在客户端断开后会保留数据 
obj:传递给回调函数的参数  
返回值:成功   客户端对象地址      
      失败    NULL 

//3.连接MQTT服务器 
int mosquitto_connect(struct mosquitto *mosq, const char *host, int port, int keepalive);
mosq:客户端对象  
host:服务器IP地址 
port:服务器端口号 👉1883 
keepalive:保持连续ping 包,设置一段时间后发送一个ping给服务器 (超时时间)
返回值: MOSQ_ERR_SUCCESS - on success.

//4.订阅主题  
int mosquitto_subscribe(struct mosquitto *mosq, int *mid, const char *sub, int qos);
mosq:客户端对象
mid:消息ID,设置为NULL不关心
sub:👍需要订阅的主题 
qos:消息质量 0,1,2
返回值: MOSQ_ERR_SUCCESS - on success.


//5.⭐重点,难点:设置消息回调函数,当订阅的主题有消息时,会调用该函数
void mosquitto_message_callback_set(struct mosquitto *mosq, 
void (*on_message)(struct mosquitto *, void *, const struct mosquitto_message *));
mosq:客户端对象
on_message:函数指针,指向一个回调函数如下👇
void on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg)
{
    /* This blindly prints the payload, but the payload can be anything so take care. */
    printf("%s %d %s\n", msg->topic, msg->qos, (char *)msg->payload);
}
mosq:客户端对象 
obj:创建客户端时传递的参数 
msg:👍消息

💡消息结构体 
struct mosquitto_message{
    int mid;      //发布消息id 
    char *topic;  //主题
    void *payload; //消息 
    int payloadlen; //消息长度  
    int qos;        //通信质量 
    bool retain;    //保留消息标记
};

6.循环接收消息   
 int mosquitto_loop_forever(struct mosquitto *mosq, int timeout, int max_packets);
 mosq:客户端对象   
 timeout:超时检测 ,设置 -1 永久等待    

订阅端代码例子:

#include <mosquitto.h> //⚠️声明MQTT库的接口
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

void on_message(struct mosquitto *mosq, void *obj, const struct mosquitto_message *msg)
{
    /* This blindly prints the payload, but the payload can be anything so take care. */
    printf("%s %d %s\n", msg->topic, msg->qos, (char *)msg->payload);
}

int main(int argc, char *argv[])
{
    // 1.初始化MQTT库
    mosquitto_lib_init();

    // 2.创建一个客户端
    struct mosquitto *mosq = mosquitto_new(NULL, true, NULL);
    if (mosq == NULL)
    {
        perror("创建客户端失败\n");
        return 1;
    }
    else
    {
        printf("创建客户成功\n");
    }

    // 3.连接服务器
    int ret = mosquitto_connect(mosq, "127.0.0.1", 1883, 60);
    if (ret != MOSQ_ERR_SUCCESS)
    {
        perror("连接服务器失败\n");
        return 1;
    }
    else
    {
        printf("连接服务器成功\n");
    }

    // 4.订阅一个主题
    ret = mosquitto_subscribe(mosq, NULL, "test", 0);
    if (ret != MOSQ_ERR_SUCCESS)
    {
        perror("订阅失败\n");
        return 1;
    }
    else
    {
        printf("订阅成功\n");
    }

    // 5.设置消息回调函数
    mosquitto_message_callback_set(mosq, on_message); // 设置接收消息回调函数

    // 6.循环接收消息
    mosquitto_loop_forever(mosq, -1, 1); // 一直循环接收数据

    mosquitto_destroy(mosq);
    mosquitto_lib_cleanup();
    return 0;
}

五、MQTTX 调试助手

公共测试服务器:免费的公共 MQTT 服务器 | EMQ

MQTTX 下载

安装

设置为简体中文

主题的订阅与发布调试

1.新建链接:服务器为你写代码的地址。

2.主题订阅:主题名字随便

3.主题发布,要跟代码的订阅一样。

4.实现MQTT远程通信

即在调试助手中(发送端)发送消息到阿里云(部署MQTT代理服务器)中,然后MQTT代理服务器转换到Ubuntu的终端中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2340473.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

学习设计模式《二》——外观模式

一、基础概念 1.1、外观模式的简介 外观模式的本质是【封装交互、简化调用】&#xff1b; 外观模式的说明&#xff1a;就是通过引入一个外观类&#xff0c;在这个类里面定义客户端想要的简单方法&#xff0c;然后在这些方法里面实现&#xff1b;由外观类再去分别调用内部的多个…

永磁同步电机控制算法-VF控制

一、原理介绍 V/F 控制又称为恒压频比控制,给定VF 控制曲线 电压是频率的tt例函数 即控制电压跟随频率变化而变化以保持磁通恒定不变。 二、仿真模型 在MATLAB/simulink里面验证所提算法&#xff0c;搭建仿真。采用和实验中一致的控制周期1e-4&#xff0c;电机部分计算周期为…

qt 配置 mysql 驱动问题:Cannot load library qsqlmysql;QMYSQL driver not loaded

项目场景&#xff1a; 环境版本&#xff1a; qt &#xff1a;5.14.2 mysql&#xff1a;8.0 windows&#xff1a;10 提示&#xff1a;qt 配置 mysql 驱动&#xff1a; 项目场景&#xff1a;qt 配置 mysql 驱动 问题描述 提示&#xff1a;这里描述项目中遇到的问题&#xff1a;…

线性代数 | 知识点整理 Ref 2

注&#xff1a;本文为 “线性代数 | 知识点整理” 相关文章合辑。 因 csdn 篇幅合并超限分篇连载&#xff0c;本篇为 Ref 2。 略作重排&#xff0c;未整理去重。 图片清晰度限于引文原状。 如有内容异常&#xff0c;请看原文。 【数学】线性代数知识点总结 阿巴 Jun 于 2024-…

华为OD机试真题——最小的调整次数/特异性双端队列(2025A卷:100分)Java/python/JavaScript/C++/C语言/GO六种最佳实现

2025 A卷 100分 题型 本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析&#xff1b; 并提供Java、python、JavaScript、C、C语言、GO六种语言的最佳实现方式&#xff01; 2025华为OD真题目录全流程解析/备考攻略/经验分享 华为OD机试真题《最小的调…

Flink-01学习 介绍Flink及上手小项目之词频统计

flink简介 官网 概述&#xff1a; 学习Flink具体包括四个关键概念&#xff1a;流数据的持续处理&#xff0c;事件时间&#xff0c;有状态流处理和状态快照。 Apache Flink 是一个开源的流处理框架&#xff0c;旨在处理批处理和实时数据处理&#xff0c;具有高吞吐量和低延迟的…

目标检测篇---R-CNN梳理

目标检测系列文章 第一章 R-CNN 目录 目标检测系列文章&#x1f4c4; 论文标题&#x1f9e0; 论文逻辑梳理1. 引言部分梳理 (动机与思想) &#x1f4dd; 三句话总结&#x1f50d; 方法逻辑梳理&#x1f680; 关键创新点&#x1f517; 方法流程图补充边界框回归 (BBR)1. BBR 的…

C#处理网络传输中不完整的数据流

1、背景 在读取byte数组的场景&#xff08;例如&#xff1a;读取文件、网络传输数据&#xff09;中&#xff0c;特别是网络传输的场景中&#xff0c;非常有可能接收了不完整的byte数组&#xff0c;在将byte数组转换时&#xff0c;因字符的缺失/增多&#xff0c;转为乱码。如下…

HTML 初识

段落标签 <p><!-- 段落标签 -->Lorem ipsum dolor sit amet consectetur adipisicing elit. Fugiat, voluptate iure. Obcaecati explicabo sint ipsum impedit! Dolorum omnis voluptas sint unde sed, ipsa molestiae quo sapiente quos et ad reprehenderit.&l…

MATLAB 训练CNN模型 yolo v4

学生对小车控制提出了更好的要求&#xff0c;能否加入深度学习模型。 考虑到小车用matlab来做&#xff0c;yolo v5及以上版本都需要在pytorch下训练&#xff0c;还是用早期版本来演示。 1 yolov4 调用 参考 trainYOLOv4ObjectDetector (mathworks.com) name "tiny-yo…

【前端】跟着maxkb学习logicflow流程图画法

文章目录 背景1. 选定学习对象-maxkb应用逻辑编排2. 确定实现框架3. 关键逻辑&#xff1a;查看app-node.js4. 学习开始节点绘制流程数据形式 5. 给节点增加表单输入框遇到过的问题 背景 看看前端如何绘制流程图&#xff0c;界面好看点。 "logicflow/core": "1.…

【漏洞复现】CVE-2024-38856(ApacheOfbiz RCE)

【漏洞复现】CVE-2024-38856&#xff08;ApacheOfbiz RCE&#xff09; 1. 漏洞描述 Apache OFBiz 是一个开源的企业资源规划&#xff08;ERP&#xff09;系统。它提供了一套企业应用程序&#xff0c;用于集成和自动化企业的许多业务流程。 这个漏洞是由于对 CVE-2023-51467 的…

超详细VMware虚拟机扩容磁盘容量-无坑版

1.环境&#xff1a; 虚拟机&#xff1a;VMware Workstation 17 Pro-17.5.2 Linux系统&#xff1a;Ubuntu 22.04 LTS 2.硬盘容量 虚拟机当前硬盘容量180G -> 扩展至 300G 3.操作步骤 &#xff08;1&#xff09;在虚拟机关机的状态下&#xff0c;虚拟机硬盘扩容之前必…

全面理解Linux 系统日志:核心文件与查看方法

全文目录 1 Linux 系统日志分类及功能1.1 通用日志1.1.1 ‌/var/log/messages1.1.2 ‌/var/log/syslog 1.2 安全相关日志1.2.1 ‌/var/log/auth.log‌&#xff08;Debian/Ubuntu&#xff09;或 ‌/var/log/secure‌&#xff08;RHEL/CentOS&#xff09;1.2.2 /var/log/audit/au…

机器学习-08-关联规则更新

总结 本系列是机器学习课程的系列课程&#xff0c;主要介绍机器学习中关联规则和协同过滤。 参考 机器学习&#xff08;三&#xff09;&#xff1a;Apriori算法&#xff08;算法精讲&#xff09; Apriori 算法 理论 重点 【手撕算法】【Apriori】关联规则Apriori原理、代码…

Flutter与FastAPI的OSS系统实现

作者&#xff1a;孙嘉成 目录 一、对象存储 二、FastAPI与对象存储 2.1 缤纷云S4服务API对接与鉴权实现 2.2 RESTful接口设计与异步路由优化 三、Flutter界面与数据交互开发 3.1 应用的创建 3.2页面的搭建 3.3 文件的上传 关键词&#xff1a;对象存储、FastAPI、Flutte…

Kubernetes控制平面组件:API Server详解(二)

云原生学习路线导航页&#xff08;持续更新中&#xff09; kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计&#xff08;一&#xff09;Kubernetes架构原则和对象设计&#xff08;二&#xff09;Kubernetes架构原则和对象设计&#xff08;三&#xff09;Kubernetes控…

MySQL-锁机制3-意向共享锁与意向排它锁、死锁

文章目录 一、意向锁二、死锁应该如何避免死锁问题&#xff1f; 总结 一、意向锁 在表获取共享锁或者排它锁时&#xff0c;需要先检查该表有没有被其它事务获取过X锁&#xff0c;通过意向锁可以避免大量的行锁扫描&#xff0c;提升表获取锁的效率。意向锁是一种表级锁&#xf…

报告系统状态的连续日期 mysql + pandas(连续值判断)

本题用到知识点&#xff1a;row_number(), union, date_sub(), to_timedelta()…… 目录 思路 pandas Mysql 思路 链接&#xff1a;报告系统状态的连续日期 思路&#xff1a; 判断连续性常用的一个方法&#xff0c;增量相同的两个列的差值是固定的。 让日期与行号 * 天数…

Tailwind 武林奇谈:bg-blue-400 失效,如何重拾蓝衣神功?

前言 江湖有云,Tailwind CSS,乃前端武林中的轻功秘籍。习得此技,排版如行云流水,配色似御风随形,收放自如,随心所欲。 某日,小侠你奋笔敲码,正欲施展“蓝衣神功”(bg-blue-400),让按钮怒气冲冠、蓝光满面,怎料一招使出,画面竟一片白茫茫大地真干净,毫无半点杀气…