博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
php 协议头,入门PHP实现MQTT协议的固定头部(Fix header)
阅读量:6361 次
发布时间:2019-06-23

本文共 1876 字,大约阅读时间需要 6 分钟。

前面的话

直接进入主题,具体的mqtt协议请参考mqtt协议

固定头的结构

e8e401d482974d54f277bedd9927ba60.png

简单描述下固定头

第一个字节总共8位, 前四位表示消息类型,最大的十进制值是15(二进制是1111)。

第三位表示消息是否重复,十进制值只能保存0或者1

第一、二位是消息的QoS值,十进制值能存0(二进制00)到3(二进制11)的任意值

最后一位是服务器是否需要保存此消息的标识,十进制值存0或者1

第二个字节标识 除了固定头部之外的 消息的 长度(可变头+消息体),这里先不讨论

_ 更具体的,请看mqtt协议。_

编码

// 先定义一个变量,值为0, 一个数字占用一个字节。

// 所以 firstByte 的二进制值是 0000 0000

// 注:有些实现使用的是16进制,使用16进制和10进制没啥区别,

// 只是16进制转换为2进制方便些,为了好理解,这里全部用10进制

$firstByte = 0;

// 假设Message Type 是5,所以构造出来的头部

// 第一字节前四位应该是 0101(5的二进制),其他位都为0的时候

// 第一字节二进制是 0101 0000

$firstByte |= 5; // 原值 0000 0000 和 0101(可以看作是:0000 0101) 做或运算,得到的值是 0000 0101

// 需要将 0000 0101 变成 0101 0000 只需要左移4位

$firstByte << 4; // $firstByte 二进制是 0101 0000 ,至此 message type 就编到了第一自己的前四位中了。

// 接下来是第三位,dup 的标识,假设我们的dug flag 值是1,我们需要将第三位设置为1

// 将firstByte 从 0101 0000 变成 0101 1000,只需要 0101 0000 和 0000 1000 做一次 或运算即可

// 0000 1000的十进制值是 8

$firstByte |= 8; // firstByte 的二进制是 0101 1000,至此 dup flag 就编到了第三位中

// 接下来是第一、二位,用存储qos level的值

// 假设qos level 的值是3(这里只是假设,3的是mqtt预留字段),3的二进制是 11

// 那么放入存储3以后,firstByte 的二进制值应该是 0101 1110

// 我们只需要将 0101 1000 和 0000 0110 作或运算即可,0000 0110 的十进制是 6

$firstByte |= 6; // firstByte 的二进制是 0101 1110

// 如何编码 retain, 相信,你已经会了

// 最后一步,我们需要将上面得到的结果转换成一个字符串

$firstChr = chr($firstByte)

// 然后发送出去

解析

//在上一步中,假设我们把 retain = 1 也编进了第一字节,那会得到 一个二进制 0101 1111。

// 通过 chr 转换为一个字符串后发出来的,我们需要还原。假设$buffer 是收到的数据.

$firstChr = substr($buffer, 0, 1); // 取第一个字节

$firstByte = ord($firstChr); // 转换回asiic码,这个时候我们就得到了一个二进制为 0101 1111的变量

// 首先取前四位,也就是message type, 只需要右移 4 位即可

$messageType = $firstByte >> 4; // 0101 1111 >> 4 = 0000 0101,值为十进制的5

// 现在要取第三位 dug flag

$dupFlag = ($firstByte & 8) >> 3; // 0101 1111 & 000 1000(8 的二进制) = 000 1000 >> 3 = 0000 0001 = 十进制1

// 取 qos level

$qos = ($firstByte & 6) >> 1; // 0101 1111 & 0000 0110(6 的二进制) = 0000 0110 >> 1 = 0000 0011 = 十进制3

// 最后一位怎么取, firstByte 和 1 作与运算即可。

结语

首先,位运算是一些很有技巧性,上面只是一种方式,你还可以通过其他的位运算方式实现

其次,不要工作几年就忘记了基础,[捂脸]

转载地址:http://sjima.baihongyu.com/

你可能感兴趣的文章
iOS 主队列同步造成死锁的原因
查看>>
es6 下比较对象是否有修改的简要方法
查看>>
windows安装mysql
查看>>
你还在看《深入理解Java虚拟机》的运行时数据模型吗?
查看>>
RIS,创建 React 应用的新选择
查看>>
线性结构上的动态规划--算法竞赛入门经典笔记
查看>>
面试官:你使用webpack时手写过loader,分离过模块吗?
查看>>
Ubuntu 16.04系统下 对OpenJDK编译好的Hotspot 进行调试
查看>>
00-利用思维导图梳理JavaSE基础知识-持续更新中!
查看>>
java中三种注释及其实际应用的意义
查看>>
【三石jQuery视频教程】01.图片循环展示
查看>>
ngrok
查看>>
ThinkPHP 模板变量输出
查看>>
android系统信息(内存、cpu、sd卡、电量、版本)获取
查看>>
Eclipse Debug Android Native Application
查看>>
java动态代理
查看>>
node.js原型继承
查看>>
揭露让Linux与Windows隔阂消失的奥秘(1)
查看>>
我的友情链接
查看>>
Mysql备份和恢复策略
查看>>