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 |
|
T | L | V |
2. 协议示例
如我们要发送两个字段设备厂家和系统版本作为应答给客户端。
则可以定义TLV编码消息体结构如下:
Tag | 0x1102 | 自定义类型,结构编码,Tag表示设备厂家(2) |
Length | 0x0005 | Value的长度为5字节 |
T | 0x0002 | 基本类型,基本编码,Tag编码表示tiny类型 |
L | 0x0001 | Value的长度为1字节 |
V | 0x01 | 值为1=xxxx |
Tag | 0x1105 | 自定义类型,结构编码,Tag表示系统版本(5) |
Length | 0x0023 | Value的长度为35字节 |
T | 0x0013 | 基本类型,基本编码,Tag编码表示string类型 |
L | 0x001F | Value的长度为31字节 |
V | version 2.6.32-573.3.1.el6.i686 | 值为”version 2.6.32-573.3.1.el6.i686” |
如上可见,上述协议虽然可以详细的描述字段值的类型,但当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 | 值为”version 2.6.32-573.3.1.el6.i686” |