当前位置:   article > 正文

TLV协议——实现封包与解析

tlv协议

1. 什么是TLV协议?

TLV,即Tag(Type)—Length—Value,是一种简单实用的数据传输方案。在TLV的定义中,可以知道它包括三个域,分别为:标签域(Tag),长度域(Length),内容域(Value)。这里的长度域的值实际上就是内容域的长度。
在这里插入图片描述
这里插入个简单应用通讯协议的例子,现在A机器通过网络socket发送数据给B机器,设定数据内容为0x14 0x30 0x47 0x33。如果没有相应的协议规范,那么B机器只是接收了这几个字节的数据,但这些数据所代表的含义就不得而知了。现在我们规定前两个字节是温度,后两个字节是湿度,那么通过这个协议,B机器就可以对接收到的数据进行解析,从而获得温度是20.48摄氏度,相对湿度是48.71%。

2. 只用TLV可能会出现问题

  • 问题1,数据可能重合!如果你设置0x01为温度,那么后面有个0x01可能是表示数据的,而不是温度!

    这时候我们需要加一个报头,固定为0xFD,用来标志一个报文的开始。

  • 问题2,数据可能会跳变!你不能保证数据传输过程中数据的跳变,0x01表示温度,跳变为0x02就表示另外的东西了!

    这时候我们需要在一个字节流末尾加一个CRC校验,传输前算一下字节流的大小,传输到另外一个端口后再算一下,对比前后两个CRC的值,如果相同,表示没有发生字节跳变,如果不同,那就舍弃!

  • 问题3,报头可能在TLV中!

    同样也要加CRC校验

加工后的TLV:在这里插入图片描述

3. 存放字节流buffer的问题

  • 如果buf定义在函数里面,是局部变量,数据存在栈中,可以用malloc,但是麻烦!

  • buf定义在函数外,但不可重入,不能用多个进程同时操作!

所以要把buf写在函数里面,用函数操作buf

pack(buf, sizeof(buf), cmd)
  • 1

还要判断buf是否合法

if( !buf || sizeof(buf)<0)
  • 1

4. TLV封包

#include<stdio.h>
#include<string.h>
#include"crc-itu-t.h"
#include"crc-itu-t.c"
 
#define     HEAD                0xFD                    //定义一个报头
#define     BUF_SIZE            128                     //定义一个buffer的大小
#define     TLV_FIXED_SIZE      5                       //固定的TLV字节流大小,不包含value值
#define     TLV_MINI_SIZE       (TLV_FIXED_SIZE+1)      //TLV字节流的最小值,value的值为1个字节
 
#define     ON                  1
#define     OFF                 0
 
enum                                                    //使用枚举,Tag的值会自加
{
    TAG_LOGON=1,                                        //登陆Tag
    TAG_CAMERA,
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/497231
推荐阅读
相关标签
  

闽ICP备14008679号