php 协议头,入门PHP实现MQTT协议的固定头部(Fix header)

前面的话

直接进入主题,具体的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 作与运算即可。

结语

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值