如何定义变长的TLV结构体?
4587 点击·0 回帖
![]() | ![]() | |
![]() | TLV是一种常用的用于通信的结构体格式。T表示tag,L表示length,V表示value。其中T和L是固定大小的,V是可变大小,L表示的是V的长度。通常用于结构化网络通信中的数据流。如0x3 3 'aa\0',0x3 5 'aaaa\0',其中0x3表示tag的值,3 or 5表示的是后面的字符串的长度。由于V是可变长度的,所以在定义TLV结构时,需要将V定义成为可变大小。可定义如下: struct TLV { uint8_t tag; uint16_t len; char value[0]; }__attribute__((packed)); 注意value分配的是0大小,最后一个成员为可变长的数组,对于TLV(Type-Length-Value)形式的结构,或者其他需要变长度的结构体,用这种方式定义最好。使用起来非常方便,创建时,malloc一段结构体大小加上可变长数据长度的空间给它,可变长部分可按数组的方式访问,释放时,直接把整个结构体free掉就可以了。__attribute__(packed)用来强制不对struct TLV进行4字节对齐,目的是为了获取真实的TLV的空间使用情况。 int main() { char *szMsg = "aaaaaaaaa"; cout << sizeof(TLV) << endl; //the size of TLV uint16_t len = strlen(szMsg) + 1; struct TLV *pTLV; pTLV = (struct TLV*)malloc(sizeof(struct TLV) + sizeof(char)*len); pTLV->tag = 0x2; pTLV->len = len; memcpy(pTLV->value, szMsg, len); cout << pTLV->value << endl; free(pTLV); pTLV = NULL; return 0; } 这里有关于设置变长TLV的详细说明: http://www.atcpu.com/kf/201206/135863.html 这里有一个问题,如何实现嵌套TLV结构呢?大家有什么好的思路吗?欢迎交流 简单实现了一下嵌套TLV,不知道有没有问题。 #include <iostream> using namespace std; struct TLVNODE { uint8_t tag; uint16_t len; char value[0]; }__attribute__ ((packed)); struct TLV { int hei; uint8_t tag; uint16_t len; struct TLVNODE value[0]; } __attribute__ ((packed)); int main() { //char *szMsg = "aaaaaaaaaaa"; cout << sizeof(TLV) << endl; //uint16_t len = strlen(szMsg) + 1; char *szNodeMsg = "bbbbbbbbbb"; uint16_t nodelen = strlen(szNodeMsg) + 1; struct TLVNODE *pNode = (struct TLVNODE *) malloc(sizeof(struct TLVNODE) + sizeof(char)*nodelen); pNode->tag = 0x3; pNode->len = nodelen; memcpy(pNode->value, szNodeMsg, nodelen); struct TLV *pTlv; uint16_t nodeSize = sizeof(struct TLVNODE) + sizeof(char)*nodelen; pTlv = (struct TLV*)malloc(sizeof(struct TLV) + nodeSize); pTlv->tag = 0x2; pTlv->len = nodeSize; // pTlv->value[0] = (struct TLVNODE)*pNode; memcpy(pTlv->value, pNode, nodeSize); free(pNode); pNode = NULL; cout << sizeof(*pTlv) << endl; /*for (int i = 0; i < len; ++i) { pTlv->value = szMsg; }*/ /*memcpy(pTlv->value, szMsg, len);*/ //cout << pTlv->value << endl; free(pTlv); pTlv = NULL; return 0; } | |
![]() | ![]() |