小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

TLV 格式及編解碼示例

 精髓_感知力 2015-07-16
 

TLV是一種可變格式,意思就是:

Type類型, Lenght長度,Value值;

Type和Length的長度固定,一般那是2、4個(gè)字節(jié)(這里統(tǒng)一采用4個(gè)字節(jié));

Value的長度有Length指定;

編碼方法:

1.       將類型type用htonl轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)順序,指針偏移+4

2.       將長度length用htonl轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)順序,指針偏移+4

3.       若值value數(shù)據(jù)類型為int、char、short,則將其轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)順序,指針偏移+4;若值為字符串類型,寫進(jìn)后,指針偏移+length

……繼續(xù)處理后面的tlv;

解碼方法:

1.       讀取type 用ntohl轉(zhuǎn)換為主機(jī)字節(jié)序得到類型,指針偏移+4

2.       讀取lengh用ntohl轉(zhuǎn)換為主機(jī)字節(jié)序得到長度;指針偏移+4

3.       根據(jù)得到的長度讀取value,若value數(shù)據(jù)類型為int、char、short,用ntohl轉(zhuǎn)換為主機(jī)字節(jié)序,指針偏移+4;若value數(shù)據(jù)類型為字符串類型,指針偏移+length

……繼續(xù)處理后面的tlv;

類型(Type)字段是關(guān)于標(biāo)簽和編碼格式的信息;

長度 (Length)字段定義數(shù)值的長度;

內(nèi)容(Value)字段表示實(shí)際的數(shù)值。

因此,一個(gè)編碼值又稱TLV(Type,Length,Value)三元組。編碼可以是基本型或結(jié)構(gòu)型,如果它表示一個(gè)簡單類型的、完整的顯式值,那么編碼就是基本型 (primitive);如果它表示的值具有嵌套結(jié)構(gòu),那么編碼就是結(jié)構(gòu)型 (constructed)。

 

下面是我寫的一個(gè)Demo程序:

  1. #include <stdio.h>   
  2. #include <WinSock2.h>   
  3. #include <string>   
  4.   
  5. #pragma comment(lib, "WS2_32")   
  6.   
  7. enum emTLVNodeType  
  8. {  
  9.     emTlvNNone = 0,  
  10.     emTlvNRoot,         //根節(jié)點(diǎn)   
  11.     emTlvName,          //名字   
  12.     emTlvAge,           //年齡   
  13.     emTlvColor          //顏色 1 白色 2 黑色   
  14. };  
  15.   
  16.   
  17. typedef struct _CAT_INFO  
  18. {  
  19.     char szName[12];  
  20.     int iAge;  
  21.     int iColor;  
  22. }CAT_INFO,*LPCAT_INFO;  
  23.   
  24. class CTlvPacket  
  25. {  
  26. public:  
  27.     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) { }  
  28.     ~CTlvPacket() { }  
  29.   
  30.     bool WriteInt(int data,bool bMovePtr = true)  
  31.     {  
  32.         int tmp = htonl(data);  
  33.         return Write(&tmp,sizeof(int));  
  34.     }  
  35.   
  36.     bool Write(const void *pDst,unsigned int uiCount)  
  37.     {  
  38.         ::memcpy(m_pWritePtr,pDst,uiCount);  
  39.         m_pWritePtr += uiCount;  
  40.         return m_pWritePtr < m_pEndData ? true : false;  
  41.     }  
  42.   
  43.     bool ReadInt(int *data,bool bMovePtr = true)  
  44.     {  
  45.         Read(data,sizeof(int));  
  46.         *data = ntohl(*data);  
  47.         return true;  
  48.     }  
  49.   
  50.     bool Read(void *pDst,unsigned int uiCount)  
  51.     {  
  52.         ::memcpy(pDst,m_pReadPtr,uiCount);  
  53.         m_pReadPtr += uiCount;  
  54.         return m_pReadPtr < m_pEndData ? true : false;  
  55.     }  
  56.   
  57. private:  
  58.     char *m_pData;  
  59.     unsigned int m_uiLength;  
  60.     char *m_pEndData;  
  61.     char *m_pWritePtr;  
  62.     char *m_pReadPtr;  
  63. };  
  64.   
  65. /* 
  66.  
  67. 格式: 
  68.     root L1 V 
  69.         T L V T L V T L V 
  70.  
  71.     L1 的長度即為“T L V T L V T L V”的長度 
  72.  
  73. */  
  74.   
  75. int TLV_EncodeCat(LPCAT_INFO pCatInfo, char *pBuf, int &iLen)  
  76. {  
  77.     if (!pCatInfo || !pBuf)  
  78.     {  
  79.         return -1;  
  80.     }  
  81.   
  82.     CTlvPacket enc(pBuf,iLen);  
  83.     enc.WriteInt(emTlvNRoot);  
  84.     enc.WriteInt(20+12+12); //根節(jié)點(diǎn)emTlvNRoot中的L,20=4+4+12,12=4+4+4,12=4+4+4   
  85.   
  86.     enc.WriteInt(emTlvName);  
  87.     enc.WriteInt(12);  
  88.     enc.Write(pCatInfo->szName,12);  
  89.   
  90.     enc.WriteInt(emTlvAge);  
  91.     enc.WriteInt(4);  
  92.     enc.WriteInt(pCatInfo->iAge);  
  93.   
  94.     enc.WriteInt(emTlvColor);  
  95.     enc.WriteInt(4);  
  96.     enc.WriteInt(pCatInfo->iColor);  
  97.   
  98.     iLen = 8+20+12+12; //總長度再加上emTLVNRoot的T和L,8=4+4   
  99.   
  100.     return 0;  
  101. }  
  102.   
  103. int TLV_DecodeCat(char *pBuf, int iLen, LPCAT_INFO pCatInfo)  
  104. {  
  105.     if (!pCatInfo || !pBuf)  
  106.     {  
  107.         return -1;  
  108.     }  
  109.   
  110.     CTlvPacket encDec(pBuf,iLen);  
  111.     int iType;  
  112.     int iSum,iLength;  
  113.   
  114.     encDec.ReadInt(&iType);  
  115.     if (emTlvNRoot != iType)  
  116.     {  
  117.         return -2;  
  118.     }  
  119.     encDec.ReadInt(&iSum);  
  120.   
  121.     while (iSum > 0)  
  122.     {  
  123.         encDec.ReadInt(&iType);  
  124.         encDec.ReadInt(&iLength);  
  125.         switch(iType)  
  126.         {  
  127.         case emTlvName:  
  128.             encDec.Read(pCatInfo->szName,12);  
  129.             iSum -= 20;  
  130.             break;  
  131.         case emTlvAge:  
  132.             encDec.ReadInt(&pCatInfo->iAge);  
  133.             iSum -= 12;  
  134.             break;  
  135.         case emTlvColor:  
  136.             encDec.ReadInt(&pCatInfo->iColor);  
  137.             iSum -= 12;  
  138.             break;  
  139.         default:  
  140.             printf("TLV_DecodeCat unkonwn error. \n");  
  141.             break;  
  142.         }  
  143.     }  
  144.   
  145.     return 0;  
  146. }  
  147.   
  148. int main(int argc, char* argv[])  
  149. {  
  150.   
  151.     int iRet, iLen;  
  152.     char buf[256] = {0};  
  153.   
  154.     CAT_INFO cat;  
  155.     memset(&cat,0,sizeof(cat));  
  156.     strcpy(cat.szName,"Tom");  
  157.     cat.iAge = 5;  
  158.     cat.iColor = 2;  
  159.   
  160.     iRet = TLV_EncodeCat(&cat,buf,iLen);  
  161.     if ( 0 == iRet )  
  162.     {  
  163.         printf("TLV_EncodeCat ok, iLen = %d. \n",iLen);  
  164.     }  
  165.     else  
  166.     {  
  167.         printf("TLV_EncodeCat error \n");  
  168.     }  
  169.   
  170.     memset(&cat,0,sizeof(cat));  
  171.     iRet = TLV_DecodeCat(buf,iLen,&cat);  
  172.     if ( 0 == iRet )  
  173.     {  
  174.         printf("TLV_DecodeCat ok, cat name = %s, age = %d, color = %d. \n",cat.szName,cat.iAge,cat.iColor);  
  175.     }  
  176.     else  
  177.     {  
  178.         printf("TLV_DecodeCat error, code = %d. \n", iRet);  
  179.     }  
  180.   
  181.     int iWait = getchar();  
  182.     return 0;  
  183. }  


本Demo程序在VC2005環(huán)境下編譯通過,下面是運(yùn)行結(jié)果截圖

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多