1. 协议消息体
1. 消息体TLV编码
协议消息体采用TLV格式编码,全部使用小字节序。TLV是一种变长编码,其中T表示Tag编码,L表示数据的长度Length,V表示数据的值Value,TLV可以嵌套表示,Value本身也可以是TLV编码。
-
Tag字段由固定2字节(Byte)组成,具体含义如下:
Tag类型(Byte1高4位) |
TLV编码(Byte1低4位) |
Tag编码(Byte2) |
0:原始类型 1:自定义类型 |
0:基本编码 1:结构编码 |
每种Tag类型共0~255个字段可用编码。 |
Byte1的高4位用于表示TLV中Tag的类型,0表示原始类型(如bool,int,string,float等,用于描述具体消息的值类型)。1表示用户自定义类型(用于描述协议中的消息)。
Byte1的低4位表示TLV的编码方式,0表示基本编码,value本身即为值。1表示结构编码,value本身是TLV格式的编码。
Byte2用于编码Tag字段的具体含义,本协议约定编码的Tag及含义如下:
基本类型,当Byte1高4位为0时的Tag编码 |
|||
Tag编码(Byte2) |
Desc |
Length |
Value |
1 |
布尔型bool |
1 |
1:true,2:false |
2 |
小整数tiny |
1 |
-127~127 |
3 |
无符号小整数utiny |
1 |
0~255 |
4 |
短整数short |
2 |
-32768~32767 |
5 |
无符号短整数ushort |
2 |
0~65535 |
6 |
整数int |
4 |
-2147483648~2147483648 |
7 |
无符号整数uint |
4 |
0~4294967295 |
8 |
长整数long |
8 |
-2^64 ~ 2^64 |
9 |
无符号长整数ulong |
8 |
0 ~2^65-1 |
10 |
单精度浮点数float |
4 |
3.4*10^-38~3.4*10^38 |
11 |
双精度浮点数double |
8 |
1.7*10^-308~1.7*10^308 |
12 |
单字符char |
1 |
ASCII |
13 |
字符串string |
可变 |
一个或多个char组成 |
14 |
复数complex |
可变 |
由1-9组成 |
15 |
空类型null |
0 |
自定义类型,当Byte1高4位为1时的Tag编码 |
|||
Tag编码(Byte2) |
Desc |
Value类型 |
Value |
1 |
设备序列号SN |
String |
如”SN180000001234” |
2 |
设备厂家 |
tiny |
1= 2= |
3 |
设备类型 |
tiny |
1= 2= |
4 |
系统类型 |
tiny |
1=linux 2=windows 3= |
5 |
系统版本 |
string |
|
6 |
硬件型号 |
string |
|
7 |
硬件版本 |
string |
|
8 |
设备出厂时间 |
uint |
自1970-01-01 00:00:00到当前时间的秒数 |
9 |
设备MAC地址 |
string |
|
10 |
设备启动时间 |
uint |
|
11 |
应用软件版本 |
string |
|
12 |
软件更新时间 |
uint |
|
13 |
软件启动时间 |
uint |
|
14 |
软件运行状态 |
tiny |
1=正常 2=异常 |
15 |
网卡描述 |
string |
|
16 |
设备IP地址 |
uint |
IP地址的整数表示 |
17 |
子网掩码 |
uint |
|
18 |
网关 |
uint |
|
19 |
DNS服务器 |
uint |
|
20 |
网卡接收字节数 |
long |
|
21 |
网卡每秒接收字节数 |
long |
|
22 |
网卡发送字节数 |
long |
|
23 |
网卡每秒发送字节数 |
long |
|
24 |
CPU描述 |
string |
|
25 |
CPU使用率 |
float |
|
26 |
GPU描述 |
string |
|
27 |
GPU使用率 |
float |
|
28 |
内存描述 |
string |
|
29 |
内存总大小 |
long |
|
30 |
内存已用大小 |
long |
|
31 |
内存空闲大小 |
long |
|
32 |
内存使用率 |
float |
|
33 |
硬盘描述 |
string |
|
34 |
硬盘总大小 |
long |
|
35 |
硬盘已用大小 |
long |
|
36 |
硬盘空闲大小 |
long |
|
37 |
硬盘使用率 |
float |
-
Length字段由固定2字节表示Value的长度,范围为0~65535。
-
Value字段表示数据的值,TLV编码方式分为基本编码和结构编码,结构编码的Value本身也是TLV格式。
基本编码:
T |
L |
V |
T |
L |
V |
结构编码:
T |
L |
|
T |
L |
|
2. 协议示例
如我们要发送两个字段设备厂家和系统版本作为应答给客户端。
则可以定义TLV编码消息体结构如下:
0x1102 |
自定义类型,结构编码,Tag表示设备厂家(2) |
|
Length |
0x0005 |
Value的长度为5字节 |
T |
0x0002 |
基本类型,基本编码,Tag编码表示tiny类型 |
L |
0x0001 |
Value的长度为1字节 |
V |
0x01 |
值为1=xxxx |
0x1105 |
自定义类型,结构编码,Tag表示系统版本(5) |
|
Length |
0x0023 |
Value的长度为35字节 |
T |
0x0013 |
基本类型,基本编码,Tag编码表示string类型 |
L |
0x001F |
Value的长度为31字节 |
V |
如上可见,上述协议虽然可以详细的描述字段值的类型,但当TLV每嵌套一层,都会有4字节增加(Tag和Length),所以一般通信双方可以按照协议对数据类型进行推定,省略第二层的Tag和Length。如确实需要可通过配置文件了解字段的类型,从而降低数据包的大小,节省流量。
则修改后的协议如下:
T |
0x1002 |
自定义类型,基本编码,Tag表示设备厂家(2) |
L |
0x0001 |
Value的长度为1字节 |
V |
0x01 |
值为1=xxxx |
T |
0x1005 |
自定义类型,基本编码,Tag表示系统版本(5) |
L |
0x001F |
Value的长度为31字节 |
V |
值为”version 2.6.32-573.3.1.el6.i686” |