发现自己写的文章更多是偏向于理论.
现在就写点实战的文章吧.
QQ浏览器返回和发送的数据都是通过JceStruct协议来传输的.当然这个传输过程是经过层层加密的.解密后的内容就是JceStruct协议.
JceStruct 协议和Protobuf 协议有点像,也是采用Key-Value的形式.但感觉比Protobuf更简洁一点.也更简单一点.
JceStruct 的内容组织形式
Key
我们先来看看Key是怎么组织的.
描述Key的类为:HeadData
public static class HeadData {
public int tag;
public byte type;
}
可以看到Key被分为了两部分,一部分是tag,一部分是type.
读取Key的函数为
public static int readHead(HeadData headData, ByteBuffer byteBuffer) {
byte b = byteBuffer.get();//获取一个byte
headData.type = (byte) (b & 0xF);//低4位为类型
headData.tag = (b & 0xF0) >> 4;//高4位为tag,
if (headData.tag != 0xF) {//如果tag为0xF 则下一个字段为tag
return 1;
}
headData.tag = byteBuffer.get() & 0xFF;
return 2;
}
函数功能非常简单.
字节低4位为type 表示序号对应的类型
字节高4位为tag 表示序号
如果tag为0xF,下一个字节为tag.
总结一下:
Key由tag和type组成
Key为1个字节或两个字节.两个字节时第二个字节为tag否则第一个字节的高4位为tag.type始终为第一个字节的低4位.
type最多有16种类型,tag最大为255.
type
根据分析type的类型如下:
值
类型
0
byte 或 bool
1
Short
2
Int
3
Long
4
Float
5
Double
6,7
String
8
Map
9
List
10
STRUCT_BEGIN 继承了JceStruct类的开始
11
STRUCT_END 继承了JceStruct类的结束
12
ZERO_TAG
Value解析
解析标准的Java类型
根据不同的类型对Value的解析就会有所不同.
其中byte,bool,Short,Int,Long, Float,Double的解析都是一样的,只不过读取的字节数不同而已.
我们以Int为例:
public int read(int i, int i2, boolean z) {
if (skipToTag(i2)) {
HeadData headData = new HeadData();
readHead(headData);
switch (headData.type) {
case (byte) 0:
return this.bs.get();
case (byte)