网络抓包学MQTT(二)---CONNECT和CONNACK包

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/FourLeafCloverLLLS/article/details/83717267

上次我们已经把环境搭建好了, 这次我们根据mqtt V3.1.1 协议的文档来学mqtt协议吧, 由于本人英语掉渣, 所以选择读中文协议手册,  这个手册网上也有, 可以去下载.

先来说说我的学习方法吧, 像协议类的和编程语言一样, 都是有自己的标准的, 我学c语言的时候是写一个很简单的程序, 然后慢慢的去毁灭它, 看他会出现什么结果, 哈哈, 有些小伙伴会想破坏???, 是不是会把电脑弄坏, 这恐怕是想多了.

好了, 接下来我们慢慢来学吧.这里我借鉴超纬电子老师的协议例子: 我们先分析老师的例子, 读懂后然后在破坏它.

connect 例子: 10 0c 00 04 4d 51 54 54 04 02 ff ff 00 00 这个包是客户端发给服务器的包, 先看看返回的是什么

返回 20 02 00 00  , 不管了 我们先分析一下包的结构

MQTT协议包的结构为

有固定报头, 可变报头, 和有效载荷构成, 我们先看看固定报头

如图所示, 那么我们应该要自导MQTT控制报文的类型有哪些?  下图控制报头的类型

看到这是否发现什么了?  我们上面的例子中第一个字节是不是10(注报文都是16进制形式的), 而10的1是不是高四位, 高四位为1的话, 报文类型应该为CONNECT  而且方向为客户端到服务器,  原来1表示控制类型, 这里弄懂了, 我们是不是要查一下用于控制报文类型的标志位??  我们找一下手册 发现

都为0 那么应该就是10中的0了, 那么到此10我们就分析完了, 那么我们应该分析第二字节的剩余长度了, 找到文档

剩余长度就是可变报头和负载的总共字节数, 而且剩余长度最大为四个字节,  如果长度小于128用一个字节编码, 低7位有效位用于编码数据, 第8位用于指示是否有更多的字节, 因此一个字节最多表示2的7次方-1=127个数值,若长度大于128, 则用多个字节表示, 例如128, 需要把第一个字节的最高位置1, 其他位置0 为0x80, 128-127=1, 那么下一个字节需要为1就行了, 这里我简单讲一下这个规律, 不过我们好少发大于128字节的报文, 所以这里不需要太纠结, 从128到16383是这样变化的, 这中间的数都是用两个字节表示, 这里是以127为界, 满127则向前面一个字节加一, 而第二个字节最多为0x7f=127, 这里也产生了为上面是127为进数, 三个字节和四个字节一样的道理, 这里就不多说了.

再看看我们例子中的0c , 0c为12, 再数数后面是不是有12个字节, 这里就对了,

接下来是可变报头:

可变报头后面还有一个表;

    这里说connect报文不需要可变报头, 那么我们暂时先不分析这块,

接下来是有效载荷了:

有效载荷connect是需要的, 那么我们分析一下

哎呀.... 一不小心就看到第三章了

这里有专门阐述14种报文类型, 我们看看connect吧, 固定报头部分:

我们已经分析过了, 那么我们就不看了, 看可变报头部分:

可变报头由这四部分组成, 我们先看看协议名吧

第一个字节为0 是不是对应例子中的00, 而第二个字节为4是不是对应为例子的04, 而MQTT这四个字母的utf8编码16进制表示是不是为4D 51 54 54 又对上了., 接下来我们看到了文档介绍协议级别:

我们的例子中下一个字节为04 也刚好对应上了, 表示为mqtt v3.1.1版本.

接下来为连接标志:

我们先看看我们例子中下一个的字节为02, 那么是应该第1为为1 其他的为0, 第1位为clean Session 我们看看这个的介绍

看到这, 懂了不?

我们着重看看第二位 遗嘱标志位

什么是遗嘱标志呢?  通俗的说就是, 如果客户端与服务器端不正常的断开连接, 那么其他客户端如果订阅了该遗嘱主题的话, 就会收到遗嘱消息, 这样的好处可以看到不正常断开的客户端, 这里说的不正常断开是指除了调用DISCONNECT报文的断开.这里我们不详细说这个, 我打算到后面着重做时间讲解.

接下来为遗嘱QoS和遗嘱保留

我们留到后面讲, 接下来为用户名和密码

我们例子中设置为0, 故为匿名登陆, 所以有效载荷中不能包含该两个字段

接下来为保持链接:

保持连接表示如果客户端一段时间没有发包给服务器, 服务器有权自动结束连接 这里为两个字节的数据, 例子中都为ff 表示希望以最长时间连接服务器, 不被断开.

接下来为有效载荷了:

有效载荷的顺序要以图中的顺序, 且至少为一个

先看看客户端标识符

我们例子中的为00 00 表示给的是一个零字节的客户端标识符, 而我们同时将清理会话标志设置为1, 则服务器会把我们看作特殊情况并分配唯一的客户端标识符, 并假设我们提供了这个唯一的客户端标识, 至此我们把connect包分析完了, 我们再看看服务器回复的包, 回复的包我们应该看

我们首先看固定报头:

这个固定报头部分都是固定的, 对应我们例子中的20 02 看看可变报头

我们首先看看连接确定标志, 只有最低位SP

我们的条件和第一条一样, 所以应该返回0

我们在看看连接返回码:

我们的为0 表示连接已接受. 到此我们就分析完我们的数据包了,  下一节我们将慢慢破坏包结构, 看是不是像协议说的那样.......

博主扣扣:1372090604  哪里错了和我联系

猜你喜欢

转载自blog.csdn.net/FourLeafCloverLLLS/article/details/83717267