写在前面

前段时间弄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 平台都支持该协议。

快速开始

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

客户端(Client)可以向服务端(Broker) 订阅(Subscribe)自己感兴趣的主题(Topic);

客户端还可以向服务端发布(Publish)关于某个主题的信息(主题不需要提前创建,发布消息时指定即可);

服务端在收到客户端发布的消息后,会将该消息转发给订阅了该主题的其他客户端。

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

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

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

brew install mosquitto

brew services start mosquitto

Mosquitto 提供了命令行工具 mosquitto_sub 和 mosquitto_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 编码的字节了。

举几个

分类:

技术点:

By © 2017 likecs 版权所有.

粤ICP备12038626号-2

Powered By WordPress . Theme by Luju

python实现mqtt协议_自己动手实现MQTT协议相关推荐

  1. dhcp协议_记录一次DHCP协议的学习过程

    DHCP 动态主机设置协议(Dynamic Host Configuration Protocol,缩写:DHCP)是一个局域网的网络协议,使用UDP协议工作. BOOTP BOOTP(Bootstr ...

  2. ethercat通讯协议_工业控制常用接口协议大全,长见识了

    I/O接口概念 I/O接口是一电子电路(以IC芯片或接口板形式出现 ),其内有若干专用寄存器和相应的控制逻辑电路构成.它是CPU和I/O设备之间交换信息的媒介和桥梁.CPU与外部设备.存储器的连接和数 ...

  3. igmp是哪个层协议_【干货】IGMPv1协议闲聊

    本期与大家聊聊IGMPv1(因特网组管理协议),分享我个人见解,以及梳理一下IGMPv1相关知识点. 一 它是干嘛用的? 我们学一个协议时,首先,最想知道的就是它是干嘛用的?什么时候才需要它?部署场景 ...

  4. java mqtt协议_基于 tio 实现 mqtt5 协议之 micamqtt

    一.简介 MQTT 全称为 Message Queuing Telemetry Transport(消息队列遥测传输)是一种基于发布/订阅范式的"轻量级"消息协议,由 IBM 发布 ...

  5. python可以plc编程_自己动手做一个PLC

    我们自己来做一个PLC(Programmable Logic Controller,即可编程逻辑控制器)怎么样?就像很多计算机专业的同学都自己写过最简单的操作系统一样,作为工控领域的软件人,怎么能不自 ...

  6. python编程100行_自己动手写100行Python代码抢火车票!

    今年你不妨自己写一段代码来抢回家的火车票,是不是很Cool. 先准备好: 1)12306网站用户名和密码 2)chrome浏览器及下载chromedriver 3)下载Python代码 代码用的Pyt ...

  7. 为什么tcp不采用停等协议_为什么TCP建立连接协议是三次握手,而关闭连接却是四次握手呢?...

    看到了一道面试题:"为什么TCP建立连接协议是三次握手,而关闭连接却是四次握手呢?为什么不能用两次握手进行连接?",想想最近也到金三银四了,所以就查阅了相关资料,整理出来了这篇文章 ...

  8. ocsp协议_什么是在线证书状态协议(OCSP)和示例教程?

    ocsp协议 Certificates like SSL, X.509 are used to secure network traffic. But every certificate has it ...

  9. mtk协议与qc协议_通用充电器快充协议QC2.0,QC3.0,MTKPE,PE+,充电识别

    通用 USB 充电器(快充)说明 .快充的意义: USB 得到广泛普及是因为其能够为外围设备供电. USB 孕育于上世纪 90 年代 中期,最初的 目的是将外部设备(例如键盘.鼠标.打印机.外置驱动器 ...

最新文章

  1. 【bzoj4916】神犇和蒟蒻 杜教筛
  2. 基于struts2的文件上传下载
  3. mysql简单创建数据库权限(待修改备注)
  4. 涨价是必然!华为P40系列今天发布,首发价再曝光
  5. 第5章 广义与一般线性模型
  6. CleanCodeHandbook Chapter 3: Linked List(20-24)
  7. windows 自带计算器 calc 的使用
  8. 字节跳动实习生转正工资_字节跳动西瓜视频招聘 | 新媒体运营实习生
  9. html 多余的字省略号,html中把多余文字转化为省略号
  10. websocket+kafka+springcloud+springboot实现报文(json)传输,解析,推送
  11. Incapsula到底是什么
  12. SP专场问题整理(一)
  13. macos 切换账户_如何在macOS上设置访客用户帐户
  14. 简易的网上购物商城首页设计流程
  15. ESIM网络结构总结以及代码详解
  16. 天边美丽的彩云——参加2012年第四届中国云计算大会有感
  17. C++压缩解压开源库ZIP
  18. 联想小新Air14 指纹解锁突然失效
  19. 进军数字货币新业务,500.com能否“涅槃”重生?
  20. vue解决Element-ui中 el-cascader 级联选择器 最后一级数据为空显示暂无数据问题

热门文章

  1. 1.定义一个结构体变量(包括年、月、日),编写程序,要求输入年、月、日,程序能判断该年是否为闰年。(闰年的条件是符合下面两者之一: ①能被4整除,但不能被100整除; ②能被100整除,又能被400整
  2. ormlite android,如何使用ormLite在android中的现有实体中添加新字段?
  3. CocoaPods安装指定版本、卸载
  4. 如何基于Java实现一套特色民宿平台系统?
  5. P2159 [SHOI2009]舞会(DP高精)
  6. 编程实现舞伴问题 c语言,C语言实现舞伴问题(队列)假设在周末舞会上,男士们(m人)和女士们(n人)进入舞厅时,各自排成一队。跳舞开始时,依次从男...
  7. Win10下 Swin Transformer目标检测环境配置流程
  8. GameFramework教程✨十四、AB包资源初始化(单机模式),与资源预加载
  9. xming+shell启动linux应用程序注意事项(xming不能启动)
  10. 雏鹅高烧不退腺病毒怎么治疗鹅腺病毒感染的症状表现