如何定义变长的TLV结构体?

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.douban.com/note/213324857/
这里 有一个问题,如何实现嵌套TLV结构呢?大家有什么好的思路吗?欢迎交流
简单实现了一下嵌套TLV,不知道有没有问题。
#include 
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[i] = szMsg[i]; 
    }
*/

     /* memcpy(pTlv->value, szMsg, len); */
     // cout << pTlv->value << endl;
    free(pTlv);
    pTlv = NULL;
     return 0;
}

你可能感兴趣的:(C,&,C++,通信)