结构体编码转换中碰到的问题

94 篇文章 1 订阅
49 篇文章 0 订阅

使用环境:

在网络通信中,使用结构体进行通信

结构体定义如下:

客户端(采用utf-16编码):

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    struct MsgHead
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
        public char[] cSenderName;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
        public char[] cRecverName;
    };

服务器端(Linux系统,采用utf-8编码):

typedef struct _MsgHead  
{  
    char cSenderName[16];  
    char cRecverName[16];  
}MsgHead, *pMsgHead;

使用iconv()函数族进行utf-16到utf-8的代码转换

代码如下:

pMsgHead convertToMsgHead(char * recvBuf, int nRecv)
{
    CCodeConverter cv=CCodeConverter("utf-16", "utf-8");

    //一个占2byte的utf-16字符在utf-8中最多用4byte    
    int nTransBufSize=2*nRecv;
    //作为转换的中介
    char * transBuf=new char[nTransBufSize];
    memset(transBuf, 0, nTransBufSize);

    int nRet=cv.convert(recvBuf, nRecv, transBuf, nTransBufSize);
    if(nRet<0)
    {
        cv.getErrInfo();
        return NULL;
    }

    pMsgHead msgHead;
    memcpy(msgHead->cSenderName, transBuf, 16);
    memcpy(msgHead->cRecverName, transBuf+16, 16);
    
    //释放转换中介缓存
    delete(transBuf);
    return msgHead;
}
出现问题:

即将接收到的结构体整体转换过去,但是发现会导致接收的时候紊乱

调试代码,如下所示:

utf-16

0

2

4

6

8

10

12

14

16

18

20

22

24

26

28

30

32

34

0

0

0

0

0

0

0

0

0

0

0

0

0

0

s

e

utf-8

0

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

0

0

0

0

0

0

0

0

0

0

0

0

0

0

s


注意:

汉字在utf-16中占2个byte,但在utf-8中占3个byte

问题解析:

把接收到的前4个byte的汉字转换成6个byte之后,其后的28个0,转换为utf-8中的14个0

这样, 导致了接收的时候无法合理的进行转换

解决办法:

逐字段的进行编码转换

代码如下:

pMsgHead convertToMsgHead(char * recvBuf, int nRecv)
{
    CCodeConverter cv=CCodeConverter("utf-16", "utf-8");

    //一个占2byte的utf-16字符在utf-8中最多用4byte    
    int nTransBufSize=2*nRecv;
    //作为转换的中介
    char * transBuf=new char[nTransBufSize];
    memset(transBuf, 0, nTransBufSize);

    pMsgHead msgHead;
    //转换字段cSenderName
    cv.convert(recvBuf, 32, transBuf, nTransBufSize);    
    memcpy(msgHead->cSenderName, transBuf, 16);
    //转换字段cRecverName
    cv.convert(recvBuf+32, 32, transBuf, nTransBufSize);
    memcpy(msgHead->cRecverName, transBuf+16, 16);
    
    //释放转换中介缓存
    delete(transBuf);
    return msgHead;
}

小结:

碰到不同编码的应用程序之间通信,而且有消息格式的限制时,最容易出现这种问题

在发送的时候也会出现类似的问题

因此,需要创建一个符合规范的发送结构体来对从utf-8要发送到utf-16客户端的消息进行规范

发送时的转换:

需要用到的匹配结构体:

typedef struct _CommMsgHead  
{  
    char cSenderName[32];  
    char cRecverName[32];  
}CommMsgHead, *pCommMsgHead;
转换代码则与接收时的转换类似,需要逐字段进行编码转换

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值