1.什么是TLV
通信协议可以理解两个节点之间为了协同工作实现信息交换,协商一定的规则和约定,例如规定字节序,各个字段类型,使用什么压缩算法或加密算法等。常 见的有tcp,udo,http,sip等常见协议。协议有流程规范和编码规范。流程如呼叫流程等信令流程,编码规范规定所有信令和数据如何打包/解包。
编码规范就是我们通常所说的编解码,序列化。不光是用在通信工作上,在存储工作上我们也经常用到。如我们经常想把内存中对象存放到磁盘上,就需要对对象进行数据序列化工作。
TLV协议也是通信协议中的一种,通常分为三部分:标签域(Tag)、长度域(Length)和内容域(Value)。通常情况下分为这三种,但很多时候为了保证数据传输的可靠性,我们通常会加上报文头(Head)和校验和(CRC) 来增加数据的可靠性!
其实说白了,当有数据发过来的时候,我们想知道这是什么数据、数据有多大以及数据内容是什么。这里的什么数据就是Tag,有多大就是Length,数据内容就是Value。通信协议就相当于两个说话前先规定说什么话双方才能听懂!通信双方的一种规约,数据应该怎么封装以及收到数据该怎么解析!
2.字节流和字符流
2.1字节流
我们上面说到的TLV协议采用的就是字节流,字节流就是按字节的方式处理和存储数据,字节流是由字节组成的。
如:0x20 0x19 0x12 0x32 0x24
2.2 字符流
字符流是由字符组成的。也就是按字符串的方式处理和存储数据。
如:例如 FileReader、FileWriter、BufferedReader
3.TLV的结构
简单的TLV结构:
有文件头和检验和的TLV结构:
复合的TLV结构:
4.简单的TLV函数封装
在我们确定了通信协议TLV之后,在传输的过程中需要对采样的数据进行函数的封装再进行发送。
代码如下:
packtlv_sn(char *buf, int size, char *sn)
{
unisgned short crc16 = 0;
int payload_len = 0;
int pack_len = 0;
int ofset = 0;
char buf[ofset];
if(!buf || size<TLV_MIN_SIZE) /*参数安全性检测*/
{
printf("Invalid input argument\n");
return 0;
}
buf[ofset] = PACK_HEADR; /* 整个TLV的文件头 */
ofset += 1;
buf[ofset] = TAG_SN; /* TLV的标签,也就是我们要的SN */
ofset += 1;
if( strlen(sn) <= size-TLV_FIXED_SIZE ) /*溢出检测*/
payload_len = strlen(sn);
else
playoad_len = strlen(sn);
pack_len = payload_len + TLV_FIXED_SIZE; /*算出length*/
buf[ofset] = pack_len; /*TLV的长度length*/
ofset += 1;
memcpy(&buf[ofset], sn, payload_len); /*TLV的Value*/
ofset += payload_len;
crc16 = crc_itu_t(MAGIC_CRC, buf, ofset); /*TLV的检验和*/
ushort_to_bytes(&buf[ofset], crc16);
ofset += 2;
return ofset;
}
上面的函数是一个子函数,是对一个叫“SN”的数据进行TLV的函数封装,将Head、Tag、Length、Value、CRC等数据写进了buf[ofset]中!