TLV是一种可变格式,意思就是:

Type类型, Lenght长度,Value值;

Type和Length的长度固定,一般那是2、4个字节(这里统一采用4个字节);

Value的长度有Length指定;

编码方法:

1.       将类型type用htonl转换为网络字节顺序,指针偏移+4

2.       将长度length用htonl转换为网络字节顺序,指针偏移+4

3.       若值value数据类型为int、char、short,则将其转换为网络字节顺序,指针偏移+4;若值为字符串类型,写进后,指针偏移+length

……继续处理后面的tlv;

解码方法:

1.       读取type 用ntohl转换为主机字节序得到类型,指针偏移+4

2.       读取lengh用ntohl转换为主机字节序得到长度;指针偏移+4

3.       根据得到的长度读取value,若value数据类型为int、char、short,用ntohl转换为主机字节序,指针偏移+4;若value数据类型为字符串类型,指针偏移+length

……继续处理后面的tlv;

类型(Type)字段是关于标签和编码格式的信息;

长度 (Length)字段定义数值的长度;

内容(Value)字段表示实际的数值。

因此,一个编码值又称TLV(Type,Length,Value)三元组。编码可以是基本型或结构型,如果它表示一个简单类型的、完整的显式值,那么编码就是基本型 (primitive);如果它表示的值具有嵌套结构,那么编码就是结构型 (constructed)。

  • #include <stdio.h>
  • #include <WinSock2.h>
  • #include <string>
  • #pragma comment(lib, "WS2_32")
  • enum emTLVNodeType
  • {
  • emTlvNNone = 0,
  • emTlvNRoot,         //根节点
  • emTlvName,          //名字
  • emTlvAge,           //年龄
  • emTlvColor          //颜色 1 白色 2 黑色
  • };
  • typedefstruct _CAT_INFO
  • {
  • char szName[12];
  • int iAge;
  • int iColor;
  • }CAT_INFO,*LPCAT_INFO;
  • class CTlvPacket
  • {
  • public:
  • CTlvPacket(char *pBuf,unsigned int len):m_pData(pBuf),m_uiLength(len),m_pEndData(m_pData+len),m_pWritePtr(m_pData),m_pReadPtr(m_pData) { }
  • ~CTlvPacket() { }
  • bool WriteInt(int data,bool bMovePtr = true)
  • {
  • int tmp = htonl(data);
  • return Write(&tmp,sizeof(int));
  • }
  • bool Write(constvoid *pDst,unsigned int uiCount)
  • {
  • ::memcpy(m_pWritePtr,pDst,uiCount);
  • m_pWritePtr += uiCount;
  • return m_pWritePtr < m_pEndData ? true : false;
  • }
  • bool ReadInt(int *data,bool bMovePtr = true)
  • {
  • Read(data,sizeof(int));
  • *data = ntohl(*data);
  • returntrue;
  • }
  • bool Read(void *pDst,unsigned int uiCount)
  • {
  • ::memcpy(pDst,m_pReadPtr,uiCount);
  • m_pReadPtr += uiCount;
  • return m_pReadPtr < m_pEndData ? true : false;
  • }
  • private:
  • char *m_pData;
  • unsigned int m_uiLength;
  • char *m_pEndData;
  • char *m_pWritePtr;
  • char *m_pReadPtr;
  • };
  • /*
  • 格式:
  • root L1 V
  • T L V T L V T L V
  • L1 的长度即为“T L V T L V T L V”的长度
  • */
  • int TLV_EncodeCat(LPCAT_INFO pCatInfo, char *pBuf, int &iLen)
  • {
  • if (!pCatInfo || !pBuf)
  • {
  • return -1;
  • }
  • CTlvPacket enc(pBuf,iLen);
  • enc.WriteInt(emTlvNRoot);
  • enc.WriteInt(20+12+12); //length
  • enc.WriteInt(emTlvName);
  • enc.WriteInt(12);
  • enc.Write(pCatInfo->szName,12);
  • enc.WriteInt(emTlvAge);
  • enc.WriteInt(4);
  • enc.WriteInt(pCatInfo->iAge);
  • enc.WriteInt(emTlvColor);
  • enc.WriteInt(4);
  • enc.WriteInt(pCatInfo->iColor);
  • iLen = 8+20+12+12;
  • return 0;
  • }
  • int TLV_DecodeCat(char *pBuf, int iLen, LPCAT_INFO pCatInfo)
  • {
  • if (!pCatInfo || !pBuf)
  • {
  • return -1;
  • }
  • CTlvPacket encDec(pBuf,iLen);
  • int iType;
  • int iSum,iLength;
  • encDec.ReadInt(&iType);
  • if (emTlvNRoot != iType)
  • {
  • return -2;
  • }
  • encDec.ReadInt(&iSum);
  • while (iSum > 0)
  • {
  • encDec.ReadInt(&iType);
  • encDec.ReadInt(&iLength);
  • switch(iType)
  • {
  • case emTlvName:
  • encDec.Read(pCatInfo->szName,12);
  • iSum -= 20;
  • break;
  • case emTlvAge:
  • encDec.ReadInt(&pCatInfo->iAge);
  • iSum -= 12;
  • break;
  • case emTlvColor:
  • encDec.ReadInt(&pCatInfo->iColor);
  • iSum -= 12;
  • break;
  • default:
  • printf("TLV_DecodeCat unkonwn error. \n");
  • break;
  • }
  • }
  • return 0;
  • }
  • int main(int argc, char* argv[])
  • {
  • int iRet, iLen;
  • char buf[256] = {0};
  • CAT_INFO cat;
  • memset(&cat,0,sizeof(cat));
  • strcpy(cat.szName,"Tom");
  • cat.iAge = 5;
  • cat.iColor = 2;
  • iRet = TLV_EncodeCat(&cat,buf,iLen);
  • if ( 0 == iRet )
  • {
  • printf("TLV_EncodeCat ok, iLen = %d. \n",iLen);
  • }
  • else
  • {
  • printf("TLV_EncodeCat error \n");
  • }
  • memset(&cat,0,sizeof(cat));
  • iRet = TLV_DecodeCat(buf,iLen,&cat);
  • if ( 0 == iRet )
  • {
  • printf("TLV_DecodeCat ok, cat name = %s, age = %d, color = %d. \n",cat.szName,cat.iAge,cat.iColor);
  • }
  • else
  • {
  • printf("TLV_DecodeCat error, code = %d. \n", iRet);
  • }
  • int iWait = getchar();
  • return 0;
  • }

转:TLV 格式及编解码示例的更多相关文章

  1. RocketMq通信协议格式及编解码 (源码分析)

    一.RocketMq broker服务器与客户端的网络通信是基于netty4.x实现的,重点分析  RocketMq设计的通信协议及对应的编解码 开发.         名字解释           ...

  2. DLib库Base64编解码示例

    代码 #include <iostream> #include <fstream> #include <sstream> #include <string&g ...

  3. Thrift源码分析(二)-- 协议和编解码

    协议和编解码是一个网络应用程序的核心问题之一,客户端和服务器通过约定的协议来传输消息(数据),通过特定的格式来编解码字节流,并转化成业务消息,提供给上层框架调用. Thrift的协议比较简单,它把协议 ...

  4. Notepad++插件Base64编解码

    我们平常进行Base64编码需要自己写代码转换, 或者使用其他人编写的小工具程序, 也可以使用在线base64编码工具, 现在我们还可以使用Notepad++自带的插件, 进行Base64编码和解码, ...

  5. 各种音视频编解码学习详解 h264 ,mpeg4 ,aac 等所有音视频格式

    编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放 license收费等 ...

  6. H.264格式,iOS硬编解码 以及 iOS 11对HEVC硬编解码的支持

    H.264格式,iOS硬编解码 以及 iOS 11对HEVC硬编解码的支持 1,H.264格式 网络表示层NAL,如图H.264流由一帧一帧的NALU组成: SPS:序列参数集,作用于一系列连续的编码 ...

  7. 视音频编解码学习工程:TS封装格式分析器

    =====================================================视音频编解码学习工程系列文章列表: 视音频编解码学习工程:H.264分析器 视音频编解码学习工 ...

  8. 视音频编解码学习工程:AAC格式分析器

    =====================================================视音频编解码学习工程系列文章列表: 视音频编解码学习工程:H.264分析器 视音频编解码学习工 ...

  9. 视音频编解码学习工程:FLV封装格式分析器

    ===================================================== 视音频编解码学习工程系列文章列表: 视音频编解码学习工程:H.264分析器 视音频编解码学习 ...

随机推荐

  1. css3新增属性:多列(column)

    css3多列能够创建多个列来对文本进行布局,就想报纸那样. 关于多列的相关属性及属性值如下: column-count: number|auto;:指定元素应分为的列数.column-fill: 指定 ...

  2. android 图片

    1,setCompoundDrawables(Drawable left, Drawable top,Drawable right, Drawable bottom) 设置图片出现在textView, ...

  3. 去BAT,你应该要看一看的面试经验总结

    我去年12月份从上一家公司离职,一直到今年3月份,基本上都在面试中度过来的. 先交代下背景:坐标上海,做技术开发,我本人面试的职位是linux服务器开发,最倾向的职位是服务器开发主程或技术经理.我本人 ...

  4. 字典(trie)树--从入门到入土

    今天再来认识一个强大的数据结构. 字典树又称单词查找树,Trie树,是一种树形结构,是一种哈希树的变种.典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词 ...

  5. Educational Codeforces Round 59 (Rated for Div. 2) (前四题)

    A. Digits Sequence Dividing(英文速读) 练习英语速读的题,我还上来昏迷一次....只要长度大于2那么一定可以等于2那么前面大于后面就行其他no 大于2的时候分成前面1个剩下 ...

  6. 计算机网络之TCP拥塞控制

    1. 首先,拥塞控制和流量控制是不一样的. 拥塞控制是防止过多的数据注入到网络中,可以使网络中的路由器或链路不致过载,是一个全局性的过程.  流量控制是点对点通信量的控制,是一个端到端的问题,主要就是 ...

  7. 彻底卸载WIN10 OneDrive

    彻底卸载WIN10 OneDrive @ECHO OFF %SystemRoot%\SysWOW64\OneDriveSetup.exe /uninstall RD "%UserProfil ...

  8. 用Jenkins构建项目实战

    登录Jenkins,新建任务 输入一个任务名称,选择一个项目类型 使用自定义工作空间:使该项目独立于系统的工作空间 自动从Git下载源码,点击添加可以增加凭证 日程表的参数: 第一个参数代表的是分钟 ...

  9. kvm使用kickstart文件自动安装系统

    假定kvm已经准备好 1.创建磁盘 qemu-img create -f qcow2 /kvm/os/vm-01.qcow2 16G 2.上传或下载安装镜像 mkdir -p /kvm/iso cd ...

  10. ps----像素与分辨率

    1.为了用于印刷,所以调整文档尺寸也很重要. 2.像素的多少决定了文件的大小,像素越多图像越清晰越逼真. 3.文档的尺寸改变需要结合分辨率. 4.像素固定的情况下修改分辨率高度宽度也会变化. 5.画面 ...