TLV(Type-Length-Value)
背景
在流式协议一章中,我们使用了固定长度头部来处理消息边界问题,但是固定长度头部按预定义的固定顺序有和长度排列,每个字段的位置和大小在协议设计时已经确定,无法动态调节。
示例:IP头部固定为20个字节,其中包含版本、TTL、源地址等字段,每个字段的位置和长度固定。
那么,如果我们考虑后期协议的拓展,固定字段就很难做出调整,这样我们就必须设计多种协议,发布多个软件版本,不容易维护。由此,大佬们就提出来了TLV(Type-Length-Value)。
TLV
1.基本结构
TLV每个字段按类型(Type)、长度(Length)、值(Value)三元组组织:
(1)Type字段
- 作用:唯一标识数据类型,决定如何解析
Value. - 编码规则
定长:通常1-4字节(如
0x01表示整数,0x02表示字符串)。
(2)Length字段
- 作用:明确
Value的字节长度,避免解析时依赖分隔符。 - **编码方式: **
- 1.定长模式:固定长度(如1字节表示
Value最大长度为255字节,4字节则表示最大长度为4GB)。 - 2.变长模式(BER编码):
- 若长度<=127,用1字节表示。
- 若长度>127,则首字节最高位必须为
1,低7位表示后续有多少字节来表示Value的长度。 - 示例:BER编码下Length字段为
0x82 0x01 0x2C,其中首字节0x82为1000 0010,其高位为1,剩余7位数值为2,表示首字节后续2位为Value的长度,即0x01 0x2C为300,表示Value的实际长度为300字节。
- 1.定长模式:固定长度(如1字节表示
(3)Value字段
- 作用:存储实际数据,格式由
Type定义。 - 常见类型:
- 基础类型:整数(大小端)、浮点数、字符串。
- 复合类型:数组、结构体,甚至是嵌套TLV。
示例
假设我们定义了一种TLV结构,其结构体定义如下:
struct TLV {
uint8_t type; // Type: 假设有三种类型分别为:整数(0x01),浮点数(0x02),字符串(0x03)
uint16_t length; // Length: 定长模式,固定2个字节大小来表示Value的长度,即最大长度为65535字节
std::string value; // Value: 实际数据内容
};
这里,我们给出以下TCP消息,然后以我们定义的TLV结构去解读一下。
[Type:0x03(1B) Length:0x0005(2B) Value:0x48656C6C6F(5B)]
1.Type:0x03(1B) ->表示类型为0x03,即为字符串类型,且该字段大小为1个字节(1B);
2.Length:0x0005(2B) ->表示长度为0x0005,即Value的长度为5个字节,该字段大小为2个字节(2B);
3.Value:0x48656C6C6F(5B) ->表示实际内容为0x48656C6C6F,因为类型是字符串,所以我们解析出来是"Hello"。
浙公网安备 33010602011771号