在网络中传输结构体

     在网络中传输结构体时,需要注意以下两点:

(1)要消除间隙,避免CPU字长不一样,造成错位;

(2)要转换字节序,避免cpu字节序不一样造成错误。

可以通过以下方式封装解封装消息。

 

xx_msg.h

#ifndef XX_MSG_H
#define XX_MSG_H

#define XX_MSG_HDR_LEN    8   /* 消息头部长度,包括type字段和length字段 */
#define XX_MAX_MSG_LEN    1024   /* 最大消息长度,只包括value字段*/

#define XX_MSG_ENCAP_8BIT(pbuff, value, encapLen) \
    do \
    { \
        unsigned char netSeqVal = 0; \
        \
        netSeqVal = (value); \
        memcpy(pbuff, &netSeqVal, 1); \
        \
        (pbuff) += 1; \
        (encapLen) += 1; \
    } \
    while(0)


#define XX_MSG_ENCAP_16BIT(pbuff, value, encapLen) \
    do \
    { \
        unsigned short netSeqVal = 0; \
        \
        netSeqVal = htons(value); \
        memcpy(pbuff, &netSeqVal, 2); \
        \
        (pbuff) += 2; \
        (encapLen) += 2; \
    } \
    while(0)


#define XX_MSG_ENCAP_32BIT(pbuff, value, encapLen) \
    do \
    { \
        unsigned int netSeqVal = 0; \
        \
        netSeqVal = htonl(value); \
        memcpy(pbuff, &netSeqVal, 4); \
        \
        (pbuff) += 4; \
        (encapLen) += 4; \
    } \
    while(0)


#define XX_MSG_ENCAP_STR(pbuff, pStr, strLen, encapLen) \
    do \
    { \
        memcpy(pbuff, pStr, strLen); \
        \
        (pbuff) += strLen; \
        (encapLen) += strLen; \
    } \
    while(0)


#define XX_MSG_DECAP_8BIT(pbuff, value, decapLen) \
    do \
    { \
        unsigned char netSeqVal = 0; \
        \
        memcpy(&netSeqVal, pbuff, 1); \
        (value) = netSeqVal; \
        \
        (pbuff) += 1; \
        (decapLen) += 1; \
    } \
    while(0)


#define XX_MSG_DECAP_16BIT(pbuff, value, decapLen) \
    do \
    { \
        unsigned short netSeqVal = 0; \
        \
        memcpy(&netSeqVal, pbuff, 2); \
        (value) = ntohs(netSeqVal); \
        \
        (pbuff) += 2; \
        (decapLen) += 2; \
    } \
    while(0)


#define XX_MSG_DECAP_32BIT(pbuff, value, decapLen) \
    do \
    { \
        unsigned int netSeqVal = 0; \
        \
        memcpy(&netSeqVal, pbuff, 4); \
        (value) = ntohl(netSeqVal); \
        \
        (pbuff) += 4; \
        (decapLen) += 4; \
    } \
    while(0)


#define XX_MSG_DECAP_STR(pbuff, pStr, strLen, decapLen) \
    do \
    { \
        memcpy(pStr, pbuff, strLen); \
        \
        (pbuff) += strLen; \
        (decapLen) += strLen; \
    } \
    while(0)


typedef int (*XX_ENCAP_MSG_FUNC_P)(unsigned char *pBuff, void *pMsg);
typedef int (*XX_DECAP_MSG_FUNC_P)(unsigned char *pBuff, void *pMsg);

typedef enum xxMsgType
{
    XX_MSG_TYPE_A,
    XX_MSG_TYPE_B,
    XX_MSG_TYPE_C,
    XX_MSG_TYPE_D,

    XX_MSG_TYPE_CNT,
}XX_MSG_TYPE_E;

typedef struct xxIpAddr
{
    int af;
    union
    {
        struct in_addr ipv4Addr;
        struct in6_addr ipv6Addr;
    }u;

}XX_IP_ADDR_S;

typedef struct xxAMsg
{
    XX_IP_ADDR_S addr;
    unsigned int a;
    unsigned short b;
    char c[40];
}XX_A_MSG_S;


extern int xx_EncapAMsg(unsigned char *pBuff, XX_A_MSG_S *pAMsg);
extern int xx_DecapAMsg(unsigned char *pBuff, XX_A_MSG_S *pAMsg);
extern int xx_EncapMsg(unsigned char *pBuff, int msgType, void *pMsg);
extern int xx_DecapMsg(unsigned char *pBuff, int msgType, void *pMsg);
extern int xx_EncapPkt(unsigned char *pBuff, int msgType, unsigned int msgLen, unsigned char *pMsgVal);
extern int xx_DecapPkt(unsigned char *pBuff, int *pMsgType, unsigned int *pMsgLen, unsigned char *pMsgVal);

#endif

xx_msg.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>


XX_ENCAP_MSG_FUNC_P gXxEncapMsgFuncTbl[XX_MSG_TYPE_CNT] =
{
    (XX_ENCAP_MSG_FUNC_P)xx_encapAMsg,
    (XX_ENCAP_MSG_FUNC_P)xx_encapBMsg,
    (XX_ENCAP_MSG_FUNC_P)xx_encapCMsg,
    (XX_ENCAP_MSG_FUNC_P)xx_encapDMsg,
}

XX_DECAP_MSG_FUNC_P gDecapMsgFuncTbl[XX_MSG_TYPE_CNT] =
{
    (XX_DECAP_MSG_FUNC_P)xx_decapAMsg,
    (XX_DECAP_MSG_FUNC_P)xx_decapBMsg,
    (XX_DECAP_MSG_FUNC_P)xx_decapCMsg,
    (XX_DECAP_MSG_FUNC_P)xx_decapDMsg,
}

int xx_EncapAMsg(unsigned char *pBuff, XX_A_MSG_S *pAMsg)
{
    unsigned int encapLen = 0;

    assert(pBuff != null);
    assert(pAMsg!= null);

    XX_MSG_ENCAP_32BIT(pBuff, pAMsg->addr.af, encapLen);
    if (pAMsg->addr.af == AF_INET)
    {
        XX_MSG_ENCAP_32BIT(pBuff, pAMsg->addr.u.ipv4Addr.s_addr, encapLen);
    }
    else
    {
        XX_MSG_ENCAP_STR(pBuff, &pAMsg->addr.u.ipv6Addr, sizeof(pAMsg->addr.u.ipv6Addr), encapLen);
    }

    XX_MSG_ENCAP_32BIT(pBuff, pAMsg->a, encapLen);
    XX_MSG_ENCAP_16BIT(pBuff, pAMsg->b, encapLen);
    XX_MSG_ENCAP_STR(pBuff, pAMsg->c, sizeof(pAMsg->c), encapLen);

    return encapLen;
}

int xx_DecapAMsg(unsigned char *pBuff, XX_A_MSG_S *pAMsg)
{
    unsigned int encapLen = 0;

    assert(pBuff != null);
    assert(pAMsg != null);

    XX_MSG_DECAP_32BIT(pBuff, pAMsg->addr.af, encapLen);
    if (pAMsg->addr.af == AF_INET)
    {
        XX_MSG_DECAP_32BIT(pBuff, pAMsg->addr.u.ipv4Addr.s_addr, encapLen);
    }
    else
    {
        XX_MSG_DECAP_STR(pBuff, &pAMsg->addr.u.ipv6Addr, sizeof(pAMsg->addr.u.ipv6Addr), encapLen);
    }
    XX_MSG_DECAP_32BIT(pBuff, pAMsg->a, encapLen);
    XX_MSG_DECAP_16BIT(pBuff, pAMsg->b, encapLen);
    XX_MSG_DECAP_STR(pBuff, pAMsg->c, sizeof(pAMsg->c), encapLen);

    return encapLen;
}

int xx_EncapMsg(unsigned char *pBuff, int msgType, void *pMsg)
{
    unsigned int encapLen = 0;

    assert(pBuff != null);
    assert(msgType >= 0);
    assert(msgType < XX_MSG_TYPE_CNT);
    assert(pMsg != null);

    assert(gXxEncapMsgFuncTbl[msgType] != null);
    encapLen = gXxEncapMsgFuncTbl[msgType](pBuff, pMsg);

    return encapLen;
}

int xx_DecapMsg(unsigned char *pBuff, int msgType, void *pMsg)
{
    unsigned int encapLen = 0;

    assert(pBuff != null);
    assert(msgType >= 0);
    assert(msgType < XX_MSG_TYPE_CNT);
    assert(pMsg != null);

    assert(gXxDecapMsgFuncTbl[msgType] != null);
    encapLen = gXxDecapMsgFuncTbl[msgType](pBuff, pMsg);

    return encapLen;
}

int xx_EncapPkt(unsigned char *pBuff, int msgType, unsigned int msgLen, unsigned char *pMsgVal)
{
    unsigned int encapLen = 0;

    assert(pBuff != null);
    assert(msgType >= 0);
    assert(msgType < XX_MSG_TYPE_CNT);
    assert(msgLen < XX_MAX_MSG_LEN);
    assert(pMsgVal != null);

    XX_MSG_ENCAP_32BIT(pBuff, msgType, encapLen);
    XX_MSG_ENCAP_32BIT(pBuff, msgLen, encapLen);
    XX_MSG_ENCAP_STR(pBuff, pMsgVal, msgLen, encapLen);

    return encapLen;
}

int xx_DecapPkt(unsigned char *pBuff, int *pMsgType, unsigned int *pMsgLen, unsigned char *pMsgVal)
{
    unsigned int decapLen = 0;

    assert(pBuff != null);
    assert(pMsgType!= null);
    assert(pMsgLen!= null);
    assert(pMsgVal != null);

    XX_MSG_DECAP_32BIT(pBuff, *pMsgType, decapLen);
    XX_MSG_DECAP_32BIT(pBuff, *pMsgLen, decapLen);
    XX_MSG_DECAP_STR(pBuff, pMsgVal, *pMsgLen, decapLen);

    return decapLen;
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值