有段时间没有写博客了,这段期间要说也够忙的(其实也没忙到哪去),从3月底到5月初这段期间一直在找暑期实习,幸运的是自己算是找到了自己希望的,从开始纠结TX,到后来确定,以及又拿到阿里的实习机会,这段过程真是够虐心的。不过自己还是选择了深圳,也许是阿里巴巴的通知有点晚,也许是自己觉得毁约去杭州有点不好,也许是因为那个QQ空间上装逼的我让我做了这个感性的决定.不管怎样,感谢阿里巴巴给的机会,也特别感谢六一、淘宝褚霸两位阿里大牛没有狠狠虐我。不多说,就以上做一个小结吧。(最近总是喜欢啰嗦)
不扯淡,今天要说的便是TLV,即Tag(Type)-Length-Value,是一中简单实用的数据传输方案。在TLV的定义中,可以知道它包括三个域,分别为:标签域(Tag),长度域(Length),内容域(Value)。这里的长度域的值实际上就是内容域的长度。
其实就是一个简单的自定义通信协议,将对应的数据进行编码、组织。我们之前自己写一个简单的C/S模型数据传输时,比如发送一个非基础类型的结点信息,就会采用struct,比如:
struct Messagebase{
unsigned int command;
char login_code[8];
char name[8];
};
这个struct描述了简单的login操作的需求信息,但是比如说有一天我们需要增加一个字段,加上login人的年龄,就需要新的一个字段:
struct Messagebase{
unsigned int command;
unsigned int birthday;
char login_code[8];
char name[8];
};
这样导致的结果就是对应解析的代码也需要进行修改,加入针对birthday字段的处理,因为原先的处理不知道数据包的第三个字段是name还是login_code,这样的处理只能用作简单的数据包扩展。
但是这个扩展有很大的局限性,总不能这么一直修改吧,所以考虑可以给每个数据段加上一个表示Tag(Type),这样就不用担心字段的任意添加了,并且对于name域来说,定长的特性肯定是不行的,所以,所以,就有了<Tag, Length, Value>三元组编码,简称TLV编码。但是需要注意的是,Value具体的含义,还是需要通信需求来决定,所以用装逼的话来说,TLV这种编码方式不具备结构化(结构未知)特点。但是TLV具备很好的扩展性,其中字段可以是结构式嵌套即value 域支持复合型元数据结构,比如如下定义:
struct tlv_entity {
unsigned char* tag; //标记
unsigned char* length; //数据长度
unsigned char* value; //数据
unsigned int tagSize; //标记占用字节数
unsigned int lengthSize; //数据长度占用字节数
tlv_entity* sub_tlventity; //子嵌套TLV实体
};
数据的发送过程其实就是打包的过程,目的是将一个从终端上发的请求数据——字节数组,构造成一系列的TLV结构实体;解包的目的刚好相反,就是将TLV结构实体解析成字节数组,所以对应我们需要一个针对TLV数据的封装处理:
class tlv_deal{
Public:
tlv_deal();
virtual ~tlv_deal();
static void construct_MS(unsigned char* buffer,unsigned int buffer_len,
tlv_entity* entity,unsigned int entity_len,unsigned int status=0 );
static void parse_MS(unsigned char* buffer,unsigned int buffer_len,
tlv_entity* entity,unsigned int entity_len);
};
对于简单的TLV数据元结构,盗图如下:
复合的TLV数据元结构:
Primitive or constructed BER-TLV data object number,包含一个简单数据元结构或者也可以是一个符合数据元结构。这样可以看出,算法中必须要实现Tag的嵌套功 能,递归算法不可少。
其实说白了,我们看到的XML等标记式的结构也是属于TLV的,以及facebook的thrift,还有google的protobuf (在这说纯属装逼,只是简单了解),基本都是TLV的例子,但是模型简单,实际的需求决定了处理的难度。哎,就算是简单的概念吧,我估计大家都没发觉自己以前写代码用了这样的概念,只是不知道名字罢了,但是真正的一个嵌套式的TLV结构,在实际应用中绝对还是不简单的,打包、解析也绝对会是体力活。额,都不知道说什么了,还是去再看看对应的应用层协议设计再来装逼吧。