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

TLV协议是一种数据传输方案,包括Tag、Length和Value三部分。文章介绍了TLV协议的基本概念,指出仅使用TLV可能存在的问题,如数据重合、跳变,并提出了解决方案,如添加报头和CRC校验。接着讨论了存放字节流buffer的注意事项,以及在封包和解析过程中如何使用memmove函数进行字节拷贝。在解析步骤中,详细阐述了如何查找帧头、验证CRC校验和处理正确的TLV报文。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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)

还要判断buf是否合法

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

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
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值