一、TLV简介
协议可以使双方不需要了解对方实现细节的情况下进行通信,因此双方可以是异构的,例如服务器可以是c,客户端可以是java,基于相同的协议,我们可以用自己熟识的语言工具来对通信发送的数据装包或解析来进行通信。当然也不只是这样,计算机通信不是通过字符串传输的,是将电信号转换为逻辑信号,其转换方式是将高低电平表示为二进制数中的1和0, 再通过不同的二进制序列来表示所有的信息。也就是将数据以二进制中的0和1的比特流的电的电压做为表示,如串口通信,波特率(bps)表示一秒钟传输多少个位(bit),将数据序列化发出去。不光是用在通信工作上,在存储工作上我们也经常用到。如我们经常想把内存中对象存放到磁盘上,就需要对对象进行数据序列化工作。但是要知道对方发过来的数据是什么意思,就需要双方对数据有约定,这就是所谓的通讯协议。
通讯协议约定中包括对数据格式,同步方式,传送速度,传送步骤,纠错方式以及控制字符定义等问题做出统一规定,通信双方必须共同遵守,倘若一方不遵守,便会直接导致数据不能被解析。常见的有tcp,udp,http等常见协议。而这些都是固定的不可修改的协议,而TLV具备了很好可扩展性。同时也具备了缺点,因为其增加了2个额外的冗余信息,tag 和len,特别是如果协议大部分是基本数据类型int ,short, byte. 会浪费几倍存储空间。另外Value具体是什么含义,需要通信双方事先得到描述文档,即TLV不具备结构化和自解释特性。TLV,即Tag(Type)-Length-Value,是一中简单实用的数据传输方案。在TLV的定义中,可以知道它包括三个域,分别为:标签域(Tag)或者称为类型域(Type),长度域(Length),内容域(Value),几乎所有的需要在卡片和终端之间传送的数据都是TLV格式的或者是TLV变种。
假设报文类型定义如下:
Tag定义
说明
长度
数据域说明
0x01
控制照明灯命令
整个TLV的长度
0x00: 关灯 0x01: 开灯
这样发来的数据0x01(控制照明灯) 0x03(总的长度,Tag类型和length长度和value数据,长度为3) 0x01(开灯),收到数据0x01 0x03 0x01就可以知道需要控制LED灯开灯。
帧头:
数据丢失可能会出错或丢失导致解析数据错误,要发的数据是0x01 0x03 0x01,但发送过程中混入了垃圾数据0x02,变成0x02 0x01 0x03 0x01一读0x02未知类型,0x01错误长度,解析错误,防止这种情况,一般采用添加加帧头数据。如加个0xFE的帧头,要发的数据是0XFE 0x01 0x04 0x01(这里定义的长度是总的TLV长度所以加了帧头之后长度变成0x04),接收到的数据0x33 0XFE 0x01 0x04 0x01,接收端就可以从帧头开始读,此时就能正确的解析出来&