写在前面

前段时间弄IoT相关的东西,系统学习了一下 MQTT 协议,在此分享出来。

本文先是对 MQTT 协议做了简单的介绍;接着是对 MQTT协议的内容做了较为全面的解读;最后使用 Python 语言去实现一个简单的 MQTT 客户端和服务器。

简介

MQTT 全称是 Message Queue Telemetry Transport,翻译成中文意思是“遥测传输协议”。它最先是由IBM提出,是一种基于 **TCP ** 协议,具有简单、轻量等优点,特别适合于受限环境(带宽低、网络延迟高、网络通信不稳定)的消息分发。MQTT 协议有 3.x, 5.x 等多个版本,目前最常用的版本是 v3.1.1 ,本文也是对此版本的协议进行的解读。MQTT 协议已纳入ISO标准 (ISO/IEC PRF 20922),现今主流的 IoT 平台都支持该协议。

PS: 更详细的信息可参考 WikipediaMQTT 官网

快速开始

MQTT 是一种发布-订阅协议,这意味着:

  • 客户端(Client)可以向服务端(Broker) 订阅(Subscribe)自己感兴趣的主题(Topic)
  • 客户端还可以向服务端发布(Publish)关于某个主题的信息(主题不需要提前创建,发布消息时指定即可);
  • 服务端在收到客户端发布的消息后,会将该消息转发给订阅了该主题的其他客户端。

我们可以在自己的电脑上运行一个 MQTT 的服务端,和多个 MQTT 的客户端来体验这一过程。

MQTT 服务端有很多可以选择。这里我们使用 Mosquitto,按照其官方文档的说明安装即可,这里不多做介绍。

Mac 用户可以用以下命令安装并启动 Mosquitto:

brew install mosquitto
brew services start mosquitto

Mosquitto 提供了命令行工具 mosquitto_submosquitto_pub ,它们可用来向服务端订阅主题 和发布消息。

在一个命令行窗口中,执行以下命令去订阅名为 “foo” 的主题:

mosquitto_sub -h 127.0.0.1 -p 1883 -t foo -q 2

在另一个命令行窗口中,执行以下命令发布消息 “Hello, MQTT” 到 “foo” 主题:

mosquitto_pub -h 127.0.0.1 -p 1883 -t foo -q 2 -m 'Hello, MQTT'

最终我们将看到,在第一个命令行窗口中,打印出了消息 “Hello, MQTT”。这意味着,第一个客户端在主题 “foo” 上,收到了第二个客户端发布的消息。

协议详解

数据包整体格式

从整体上看,数据包分为3个部分:一个是固定头部,它是一定存在的;另一个是可变头部,它不一定存在;剩下一个是载荷,它也不一定存在。数据采用大端方式存储。

+----------------------------+
| |
| 固 定 头 部 (必 需 ) |
| |
+----------------------------+
| |
| 可 变 头 部 (非 必 需) |
| |
+----------------------------+
| |
| 载 荷 (非 必 需 ) |
| |
+----------------------------+

固定头部(Fixed header)

固定头部格式如下:

+---------------------------------------------------------+
| bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+---------------------------------------------------------+
| byte1 | Packet type | Flags |
+---------------------------------------------------------+
| byte2...| Remaining Length |
+---------------------------------------------------------+
包类型(Packet type)
Name Value Direction of flow Description
Reserved 0 Forbidden Reserved
CONNECT 1 Client to Server Client request to connect to Server
CONNACK 2 Server to Client Connect acknowledgment
PUBLISH 3 Client to Server or Server to Client Publish message
PUBACK 4 Client to Server or Server to Client Publish acknowledgment
PUBREC 5 Client to Server or Server to Client Publish received (assured delivery part 1)
PUBREL 6 Client to Server or Server to Client Publish release (assured delivery part 2)
PUBCOMP 7 Client to Server or Server to Client Publish complete (assured delivery part 3)
SUBSCRIBE 8 Client to Server Client subscribe request
SUBACK 9 Server to Client Subscribe acknowledgment
UNSUBSCRIBE 10 Client to Server Unsubscribe request
UNSUBACK 11 Server to Client Unsubscribe acknowledgment
PINGREQ 12 Client to Server PING request
PINGRESP 13 Server to Client PING response
DISCONNECT 14 Client to Server Client is disconnecting
Reserved 15 Forbidden Reserved
标记(Flags)

不同包类型标记位含义不尽相同,具体情况如下表所示:

Control Packet Fixed header flags Bit 3 Bit 2 Bit 1 Bit 0
CONNECT Reserved 0 0 0 0
CONNACK Reserved 0 0 0 0
PUBLISH Used in MQTT 3.1.1 DUP1 QoS2 QoS2 RETAIN3
PUBACK Reserved 0 0 0 0
PUBREC Reserved 0 0 0 0
PUBREL Reserved 0 0 1 0
PUBCOMP Reserved 0 0 0 0
SUBSCRIBE Reserved 0 0 1 0
SUBACK Reserved 0 0 0 0
UNSUBSCRIBE Reserved 0 0 1 0
UNSUBACK Reserved 0 0 0 0
PINGREQ Reserved 0 0 0 0
PINGRESP Reserved 0 0 0 0
DISCONNECT Reserved 0 0 0 0
剩余长度(Remaining Length)

Remaining Length 表示的是本数据包剩余部分的字节数,即可变头部和载荷的字节数之和。为了节省传输时的字节数,Remaining Length 采用的是一种变长编码方式。这就是说 Remaining Length 字段的字节数不是固定的,它可能使用1~4个字节。既然 Remaining Length 的字节数是可变的,那么问题来了,我们在解码包数据的时候,怎么知道 Remaining Length 究竟是使用几个字节编码的呢?解决这个问题的办法是,将每个字节的最高位(MSB)作为标志位。若该位的值是1,则意味着下一个字节属于参与 Remaining Length 编码的字节;若该位的值是0,则意味着本字节已经是最后一个参与 Remaining Length 编码的字节了。

举几个

自己动手实现MQTT协议的更多相关文章

  1. 海鑫智圣:物联网漫谈之MQTT协议

    什么是MQTT协议 MQTT(消息队列遥测传输协议)是IBM在1999年专门针对物联网等应用场景来制订的轻量级双向消息传输协议,它主要是为了解决物联网上使用到的设备的互相通信的问题,以及这些设备与后端 ...

  2. 基于MQTT协议进行应用开发

    官方协议有句如下的话来形容MQTT的设计思想: "It is designed for connections with remote locations where a "sma ...

  3. 云巴:基于MQTT协议的实时通信编程模型

    概要 有人常问,云巴实时通信系统到底提供了一种怎样的服务,与其他提供推送或 IM 服务的厂商有何本质区别.其实,从技术角度分析,云巴与其它同类厂商都是面向开发者的通信服务,宏观的编程模型都是大同小异, ...

  4. MQTT协议(一)

    MQTT(Message Queue Telemetry Transport),遥测传输协议,提供订阅/发布模式,更为简约.轻量,易于使用,针对受限环境(带宽低.网络延迟高.网络通信不稳定),可以简单 ...

  5. MQTT协议的简单介绍和服务器的安装

    最近公司做的项目中有用到消息推送,经过多方面的筛选之后确定了使用MQTT协议,相对于XMPP,MQTT更加轻量级,并且占用用户很少的带宽. MQTT是IBM推出的一种针对移动终端设备的基于TCP/IP ...

  6. MQTT协议学习笔记

    1.前沿 万物联网的时代即将到来,物联网也由当初的概念开始进一步落实.随着无线网络技术飞速发展,各种设备都可以连接网络,实现远程控制.例如智能家居最近非常火爆,智能插座.智能LED灯.智能摄像头等.在 ...

  7. 【转载】MQTT学习笔记——MQTT协议体验 Mosquitto安装和使用

    http://blog.csdn.net/xukai871105/article/details/39252653 0 前言     MQTT是IBM开发的一个即时通讯协议.MQTT是面向M2M和物联 ...

  8. 转:XMPP协议、MQTT协议、HTTP协议、CoAP协议的基本比较

    一.先看下相关国外的专业数据对四大协议的比较: Protocol                                    CoAP                         XMP ...

  9. 物联网MQTT协议分析和开源Mosquitto部署验证

    在<物联网核心协议—消息推送技术演进>一文中已向读者介绍了多种消息推送技术的情况,包括HTTP单向通信.Ajax轮询.Websocket.MQTT.CoAP等,其中MQTT协议为IBM制定 ...

随机推荐

  1. Bzoj 3166 [Heoi2013] Alo 题解

    3166: [Heoi2013]Alo Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 1118  Solved: 518[Submit][Status ...

  2. idea中向pom.xml添加依赖时显示”not found dependency“

    总结: 起因:再输入hibernate-core的version时,开始写的是对的,就是 5.0.11.Final(这个也是跟着教程来的),直接就报错了,左等右等没用,也点过maven的reimpor ...

  3. python笔记(1)--序列(列表 元组 range)

    一.序列分类 1.可变序列:list 2.不可变序列:tuple,range 二.序列公共操作方法 1.操作和返回值 其中s和t代表同类型序列:n,i,j,k为整数:x为任意类型. 序号 操作 结果 ...

  4. Windows 10打开远程桌面的方法

    今天使用windows 10,想要用远程桌面连接,可是怎么都找不到,哎,win10相比于win7和XP系统,感觉还是有点使用不习惯.不过后来还是找到了两个方法,在此记录下来,分享给需要的朋友. 1. ...

  5. 20131209-数据库导入导出数据-sqlhelper-第十七天

    [1] 导出数据 namespace _05导出数据 { class Program { static void Main(string[] args) { string str = "Da ...

  6. springcloud-高可用部署

    1.场景描述 前端时间只简单介绍了下springcloud的高可用方案(springcloud高可用方案),今天详细介绍下如何实施springcloud的高可用部署. 2.解决方案 2.1 架构方案 ...

  7. YuniKorn 介绍

    一.YuniKorn 简介 YuniKorn 是一种轻量级的通用资源调度程序,适用于容器编排系统.它的创建是为了一方面在大规模,多租户环境中有效地实现各种工作负载的细粒度资源共享,另一方面可以动态地创 ...

  8. PJzhang:python基础入门的7个疗程-five

    猫宁!!! 参考链接:易灵微课-21天轻松掌握零基础python入门必修课 https://www.liaoxuefeng.com/wiki/1016959663602400 第十三天:代码组织 类是 ...

  9. 个人永久性免费-Excel催化剂功能第30波-工作表快捷操作(批量创建、命名、排序、工作表目录)

    日常使用Excel过程中,最多的操作无外乎单元格和工作表的操作,单元格的操作在前面已经有详细的辅助功能提供,此篇提供工作表相关的操作.这两项的操作若能有提速,日常大量的工作叠加起来真是省下不少时间. ...

  10. 编译Tomcat9源码及tomcat乱码问题解决

    因工作原因,需要从根本上优化tomcat的配置,故准备从源码入手,看看可以做哪些工作. 1. tomcat下载 tomcat最新的版本为9,下载源码的方式有3种: 1/ 官方网站 https://to ...