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

来源:互联网 发布:linux修改22端口 编辑:程序博客网 时间:2024/06/05 02:41

使用环境:

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

结构体定义如下:

客户端(采用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;
转换代码则与接收时的转换类似,需要逐字段进行编码转换

原创粉丝点击