mqtt协议剩余长度字段编解码实现方案(java)
mqtt协议报文解析,参考:http://www.jiajiajia.club/blog/artical/kdv1qvpfgbh4/514
根据mqtt协议的定义,剩余长度字段是可变的,最少用一个字节最多四个字节来表示,而且每个字节的最高位不表示有效数据,用来表示有没有下一个字节。所以每个字节能表示的数据的最大值是128,所以剩余长度字段可表示的最大值是128 * 128 * 128 * 128
,则理论上能表示数据包大小的最大值是256M。
对剩余长度字段的编解码,可理解为128进制的运算。如果低位字节满128,则向高位字节进1。那么进位系数就是128。
下面是用一段代码描述对剩余长度字段的计算方法(java实现)。
public static void main(String[] args) throws Exception{
int length = 300;
final byte[] encode = encode(length);
System.out.println("编码:"+length);
for (byte b : encode) {
System.out.println(getBinaryStrFromByte(b));
}
System.out.println();
System.out.println("解码:"+decode(encode));
}
/**
* mqtt固定报文头剩余长度的编码方案
* @param x 字节大小
* @return 编码结果
*/
public static byte[] encode(int x){
byte encodeBytes[] = new byte[x < 2<<6 ? 1 : x < 2<<13 ? 2 : x < 2<<20 ? 3 : 4];
int encodeByte;
int i=0;
do{
// 128进制,满128进1
encodeByte = x % 128;
x = x / 128;
if( x > 0 )
// encodeByte | 128 保证最高位必须是1
encodeByte = encodeByte | 128;
encodeBytes[i]=(byte)encodeByte;
i+=1;
}while (x>0);
return encodeBytes;
}
/**
* mqtt固定报文头剩余长度的编码方案
* @param bytes 编码后的字节数据
* @return 解码后的字节剩余长度
*/
public static int decode(byte[] bytes){
// multiplier 进位系数,第一个字节的进位系数是1,第二个字节的进位系数是128,
// 第三个字节的进位系数是 128 * 128,第四个字节的进位系数是 128 * 128 * 128
int multiplier = 1;
int value = 0;
int i=0;
byte encodedByte;
do {
encodedByte = bytes[i];
// encodedByte & 127 去掉最高位的1,因为最高位不表示数据
value += (encodedByte & 127) * multiplier;
multiplier *= 128;
if (multiplier > 128 * 128 * 128)
return -1;
i+=1;
// (encodedByte & 128) != 0 代表encodedByte该字节的最高位是1,
// 所以根据mqtt对剩余字段长度的定义应该还有下一个字节。
}while ((encodedByte & 128) != 0);
return value;
}
/**
* 字节转二进制字符串
* @param encodeByte byte
* @return 二进制字符串
*/
public static String getBinaryStrFromByte(byte encodeByte){
StringBuilder result = new StringBuilder();
byte a = encodeByte; ;
for (int i = 0; i < 8; i++){
int i1 = a % 2;
result.append(i1>0?i1:-i1);
a=(byte)(a>>1);
}
return result.reverse().toString();
}
评论区
请写下您的评论...
猜你喜欢
blog
mqtt 协议报文解析
mqtt协议
1975
(0xFF,0xFF,0xFF,0x7F)例如:可变头部和Payload(有效负载)的总字节数是300个字节。则剩余长度字段的表示如下:1010110000000010关于剩余长度字段编解码的计算方法可以参考
blog
mqtt 协议的概念和理解
mqtt协议
1589
/订阅(publish/subscribe)模式的”轻量级”通讯协议,该协议构建于TCP/IP协议上,由IBM在1999年发布。MQTT最大优点在于,可以以极少的代码和有限的带宽,为连接远程设备提供实
blog
java实现mqtt客户端案例
mqtt协议
972
pom依赖dependencygroupIdorg.eclipse.paho/groupIdartifactIdorg.eclipse.paho.client.mqttv3/artifactIdversion1.2.0/version/dependency发布端importorg.eclipse.paho.client.mqttv3.MqttClient;importorg.eclipse.pah
official
1157
UpdaterequestHTTP包建立起连接,之后的通信全部使用websocket自己的协议,就和http没啥关系了。有兴趣的同学可以多了解一下websocket协议报文的详细信息。Netty实现websoc
框架
3334
例:java类如下:publicclassQuestionnaireSubject{ privateIntegerid; privateStringname; publicIntegergetId
blog
mqtt 协议中的 QoS等级介绍
mqtt协议
4215
一次;QoS1,Atleastonce,至少一次;QoS2,Exactlyonce,确保只有一次; QoS是消息的发送方(Sender)和接受方(Receiver)之间达成的一个协议:QoS0代表,S
数据结构和算法
1172
/*** 链表节点类*@author硅谷探秘者(jia)*/classNode{ publicintdata; publicNodenext; publicNode(intdata){ this.data=data; } publicNode(Nodenext,intdata){ this.data=data; this.next=next; }}publicclassA3{ publics
keepalived,nginx,linux
1600
LVS负载均衡软件设计的,用来管理并监控LVS集群系统中各个服务节点的状态,后来又加入了可以实现高可用的VRRP(VirtualRouterRedundancyProtocol,虚拟路由器冗余协议)功
最新发表
归档
2018-11
12
2018-12
33
2019-01
28
2019-02
28
2019-03
32
2019-04
27
2019-05
33
2019-06
6
2019-07
12
2019-08
12
2019-09
21
2019-10
8
2019-11
15
2019-12
25
2020-01
9
2020-02
5
2020-03
16
2020-04
4
2020-06
1
2020-07
7
2020-08
13
2020-09
9
2020-10
5
2020-12
3
2021-01
1
2021-02
5
2021-03
7
2021-04
4
2021-05
4
2021-06
1
2021-07
7
2021-08
2
2021-09
8
2021-10
9
2021-11
16
2021-12
14
2022-01
7
2022-05
1
2022-08
3
2022-09
2
2022-10
2
2022-12
5
2023-01
3
2023-02
1
2023-03
4
2023-04
2
2023-06
3
2023-07
4
2023-08
1
2023-10
1
2024-02
1
2024-03
1
2024-04
1
2024-08
1
标签
算法基础
linux
前端
c++
数据结构
框架
数据库
计算机基础
储备知识
java基础
ASM
其他
深入理解java虚拟机
nginx
git
消息中间件
搜索
maven
redis
docker
dubbo
vue
导入导出
软件使用
idea插件
协议
无聊的知识
jenkins
springboot
mqtt协议
keepalived
minio
mysql
ensp
网络基础
xxl-job
rabbitmq
haproxy
srs
音视频
webrtc
javascript
加密算法
目录
没有一个冬天不可逾越,没有一个春天不会来临。最慢的步伐不是跬步,而是徘徊,最快的脚步不是冲刺,而是坚持。