[网络编程]mqtt概念&数据包
前言
本笔记记录 MQTT 相关概念。
原文:李柱明博客:https://www.cnblogs.com/lizhuming/p/14994943.html
1. MQTT 简介
MQTT(Message Queuing Telemetry Transport)是运行在 TCP/IP 中的应用层协议,主流依赖于 TCP 协议。(也有依赖于 UDP 的)
特点:
- 开放消息协议,简单易实现。
- 发布订阅模式,一对多消息发布。
- 基于TCP/IP网络连接,提供有序,无损,双向连接。
- 1字节固定报头,2字节心跳报文,最小化传输开销和协议交换,有效减少网络流量。
- 消息QoS支持,可靠传输保证。
特性:
- 使用发布/订阅消息模式,提供一对多的消息发布,解除应用程序耦合。
- 对负载内容屏蔽的消息传输。
- 使用TCP/IP提供网络连接。
- 有三种消息发布服务质量:
- QoS0:最多发送一次消息,在消息发送出去后,接收者不会发送回应,发送者也不会重发消息。
- QoS1:最少发送一次消息(消息最少需要送达一次,也有可送达多次),QoS 1的PUBLISH报文的可变报头中包含一个报文标识符,需要PUBACK报文确认。即需要接收者返回PUBACK应答报文。
- QoS2:这是最高等级的服务质量,消息丢失和重复都是不可接受的,只不过使用这个服务质量等级会有额外的开销。
- 小型传输,开销很小(固定长度的头部是2字节),协议交换最小化,以降低网络流量。
- 使用Last Will和Testament特性通知有关各方客户端异常中断的机制:
- Last Will:即遗言机制,用于通知同一主题下的其他设备发送遗言的设备已经断开了连接。
- Testament:遗嘱机制,功能类似于Last Will。
2. MQTT 通信模型
通信模型:

2.1 MQTT 协议
MQTT 协议中有三种身份:
- 发布者(Publish):客户端。消息发布者也可以同时是订阅者。
- 服务器(Broker):服务端。
- 订阅者(Subscribe):客户端。
MQTT 传输的消息分为:主题(Topic)和负载(payload):
- Topic:可以理解为消息的类型,订阅者订阅(Subscribe)后,就会收到该主题的消息内容(payload)。
- 发布者与订阅者可以通过主题名字进行匹配的。
- payload:可以理解为消息的内容,是指订阅者具体要使用的内容。
2.2 MQTT 协议中的订阅&主题&会话
订阅(Subscription):
- 订阅包含主题筛选器(Topic Filter)和最大服务质量(QoS)。
- 订阅会与一个会话(Session)关联。一个会话可以包含多个订阅。每一个会话中的每个订阅都有一个不同的主题筛选器。
会话(Session):
- 每个客户端与服务器建立连接后就是一个会话,客户端和服务器之间有状态交互。
- 会话存在于一个网络之间,也可能在客户端和服务器之间跨越多个连续的网络连接。
主题名(Topic Name):
- 连接到一个应用程序消息的标签,该标签与服务器的订阅相匹配。
- 服务器会将消息发送给订阅所匹配标签的每个客户端。
主题筛选器(Topic Filter):
- 一个对主题名通配符筛选器,在订阅表达式中使用,表示订阅所匹配到的多个主题。
负载(Payload):
- 消息订阅者所具体接收的内容。
2.3 MQTT 协议中的方法
主要方法有:
- Connect:等待与服务器建立连接。
- Disconnect:等待MQTT客户端完成所做的工作,并与服务器断开TCP/IP会话。
- Subscribe:等待完成订阅。
- UnSubscribe:等待服务器取消客户端的一个或多个topics订阅。
- Publish:MQTT客户端发送消息请求,发送完成后返回应用程序线程。
3. MQTT 协议数据包结构
一个MQTT数据包由三部分组成:
- 固定报头(Fixed header):表示数据包类型及数据包的分组类标识。
- 可变报头(Variable header):数据包类型决定了可变头是否存在及其具体内容。
- 有效载荷(payload):表示客户端收到的具体内容。
3.1 固定报头
固定报头组成:

控制报文的类型 [7:4]:
- 4 bit,共16种。(0、15被系统保留了)
| 类型 | 值 | 说明 |
|---|---|---|
| Reserved | 0 | 系统保留 |
| CONNECT | 1 | 客户端请求连接服务端 |
| CONNACK | 2 | 连接报文确认 |
| PUBLISH | 3 | 发布消息 |
| PUBACK | 4 | 消息发布收到确认(QoS 1) |
| PUBREC | 5 | 发布收到(QoS2) |
| PUBREL | 6 | 发布释放(QoS2) |
| PUBCOMP | 7 | 消息发布完成(QoS2) |
| SUBSCRIBE | 8 | 客户端订阅请求 |
| SUBACK | 9 | 订阅请求报文确认 |
| UNSUBSCRIBE | 10 | 客户端取消订阅请求 |
| UNSUBACK | 11 | 取消订阅报文确认 |
| PINGREQ | 12 | 心跳请求 |
| PINGRESP | 13 | 心跳响应 |
| DISCONNECT | 14 | 客户端断开连接 |
| Reserved | 15 | 系统保留 |
控制报文类型的标志位 [3:0]:
- 目前除了 PUBLISH类型报文 以外,其他报文的标志位均为系统保留。
- PUBLISH类型报文的标志位:
- bit3:控制报文的重复分发标志(DUP)。
- bit2-bit1:服务质量等级。
- 00:QoS0。
- 01:QoS1。
- 10:QoS2。
- 11:预留。
- bit0:PUBLISH 报文的保留标志。
剩余长度:(第二byte开始)
- 用于记录剩余报文长度的,表示当前的消息剩余的字节数。包括可变报头和有效载荷区域(如果存在),但剩余长度不包括用于编码剩余长度字段本身的字节数。
- 剩余长度使用变长编码方案:(大端模式)
- 每个字节的 [bit7] 表示剩余长度是否还有更多字节表示。
- 0:无。即是本字节为最后也给字节标识。
- 1:有。
- 每个字节的 [6:0]bit 表示编码数据长度。
- 如:127:只需要一个字节即可:0x7F。128:需要两个字节:0x80、0x01。
- 每个字节的 [bit7] 表示剩余长度是否还有更多字节表示。
3.2 可变报头
只有某些MQTT报文才有可变报头。
位于固定报头和有效负载之间。
可变报头的内容会根据报文类型的不同而有所不同。
3.3 有效载荷
有效载荷也是存在与某些报文中,不同的报文有效载荷也是不一样的。
Payload有效载荷位于MQTT数据包的第三部分,包含CONNECT、SUBSCRIBE、SUBACK、UNSUBSCRIBE四种类型的消息:
- CONNECT:主要是:客户端的ClientID、订阅的Topic、Message以及用户名和密码。
- SUBSCRIBE:是一系列的要订阅的主题以及QoS。
- SUBACK:是服务器对于SUBSCRIBE所申请的主题及QoS进行确认和回复。
- UNSUBSCRIBE:是要订阅的主题。
参考
链接:
- MQTT:https://mqtt.org/
- MQTT手册:http://mqtt.p2hp.com/
- 项目网站:https://www.eclipse.org/paho/
- Eclipse项目信息:https://projects.eclipse.org/projects/iot.paho
- mosquitto:http://mosquitto.org/documentation/
- ubuntu安装mosquitto:https://www.jianshu.com/p/37f7ee7ead65
- CONNECT报文格式:http://www.blogjava.net/yongboy/archive/2014/02/09/409630.html
[网络编程]mqtt概念&数据包的更多相关文章
- [转]C#网络编程(基本概念和操作) - Part.1
本文转自:http://www.tracefact.net/CSharp-Programming/Network-Programming-Part1.aspx 引言 C#网络编程系列文章计划简单地讲述 ...
- 健壮的网络编程IO函数-RIO包
RIO包 简介 Rio包即为Robust io函数包.包中函数是对Linux基本I/O函数的封装,使其更加健壮.高效,更适用于网络编程. 分析 Rio包由rio_t结构体和系列函数组成. 首先是两个不 ...
- C#网络编程(基本概念和操作) - Part.1
引言 C#网络编程系列文章计划简单地讲述网络编程方面的基础知识,由于本人在这方面功力有限,所以只能提供一些初步的入门知识,希望能对刚开始学习的朋友提供一些帮助.如果想要更加深入的内容,可以参考相关书籍 ...
- 网络_OSI模型_数据包传输
2017年1月12日, 星期四 网络_OSI模型_数据包传输 1. 网络_源主机_局域网_交换机_路由器_目标主机 2. OSI7七层_TCP/IP精简 OSI 7层: 应用层 ...
- Java 网络编程----基本概念
网络现在是一个非常普遍的概念. 以下是维基百科上的解释: 网络一词有多种意义,可解作: 网络流也简称为网络(network).一般用于管道系统.交通系统.通讯系统建模. 有时特指计算机网络. 或特指其 ...
- 【网络编程2】网络编程基础-发送ICMP包(Ping程序)
IP协议 网络地址和主机协议 位于网络层的协议,主要目的是使得网络能够互相通信,该协议使用逻辑地址跨网络通信,目前有两个版本IPV4,IPV6. 在IPV4协议中IP地址是一个32位的数备,采用点分四 ...
- JAVA的网络编程基础概念
网络编程的目的就是指直接或间接地通过网络协议与其他计算机进行通讯.网络编程中有两个主要的问题,一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输.在TCP/IP协 ...
- (网络编程)基于tcp(粘包问题) udp协议的套接字通信
import socket 1.通信套接字(1人1句)服务端和1个客户端 2.通信循环(1人多句)服务端和1个客户端 3.通信循环(多人(串行)多句)多个客户端(服务端服务死:1个客户端---&g ...
- Android移动网络如何抓取数据包
1)下载tcpdump工具 tcpdump(dump the traffic on a network)是Linux中强大的网络数据采集分析工具之一,可以将网络中传送的数据包头完全截获下来提供分析.它 ...
随机推荐
- shell基础之综合练习
0.脚本一键完成下面所有操作1.准备2台centos7系统的服务器,远程互相免密登录,以下所有题目过程中开启防火墙2.给1号机和2号机使用光盘搭建本地yum源(永久生效)3.给服务器1添加2块硬盘,1 ...
- 2.7循环_while
循环 目标 程序的三大流程 while 循环基本使用 break 和 continue while 循环嵌套 01. 程序的三大流程 在程序开发中,一共有三种流程方式: 顺序 -- 从上向下,顺序执行 ...
- #undef 与 exit(0) 使用
#undef 与 #defined 反,实际使用中较多的是当你需要使用自己定义的标准C里面已经的函数时可以这样操作: exit(0)和exit(1)是系统判断函数是否有正常的退出,一般0表示正常的退 ...
- linux(centos 7)下安装JDK,Tomcat,mysql 运行Maven 项目
一.在Linux中安装JDK 1. 将JDK上传到root下(任何位置均可以). 如图: 2. 用解压命令解压JDK tar -xvf (此处为jdk文件名) 如果是rpm包,执行rpm -i jdk ...
- 安装JDK 常见错误解决(Day_07)
在cmd中输入java -version或者java 或出现以下错误: 原因一:可能是你的JDK装的时间比较早,导致环境变量中的Path(此电脑->右击属性->高级系统设置->环境变 ...
- 【遥感数字图像处理实验】Erdas版详细图文实验教程(8实验全)
@ 目录 1. 专栏简介 2. 专栏地址 3. 专栏目录 1. 专栏简介 遥感数字图像的处理,是对遥感数字图像的计算机处理.与工业和医学数字图像不同,遥感数字图像类型更为多样,内容更为复杂.因此,遥感 ...
- Django使用Ace实现在线编辑器
前言:最近自己开发SQL工单功能,期间接触到了Ace在线编辑器,折腾一下,感觉功能挺多,特意去了解学习一下分享跟大家. ACE 是一个功能非常强大的编辑器,实现语法高亮.代码补全功能,还有很多主题,支 ...
- pika详解 (一)
pika详解 (一) 本文链接:https://blog.csdn.net/comprel/article/details/94592316 pika pika处理消息可以简单分为以下几个步骤: 我们 ...
- 【转载】NBU异机恢复oracle
通过NBU将Oracle恢复到异机上... 2 1.1 备份任务检查: 2 1.2 数据库空间检查... 2 1.3 恢复服务器(testdb)软件安装:... 3 ...
- JavaScript 中数组 sort() 方法的基本使用
在日常的代码开发中,关于数组排序的操作可不少,JavaScript 中可以调用 sort 方法对数组进行快速排序. 今天,就数组的 sort 方法来学习一下,避免日后踩坑的悲惨遭遇. 概念 sort ...