结构体编码转换中碰到的问题
来源:互联网 发布: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;转换代码则与接收时的转换类似,需要逐字段进行编码转换
- 结构体编码转换中碰到的问题
- 使用ajax中碰到的编码问题
- Python3碰到的编码问题
- 碰到的一个编码问题
- 传输请求中碰到字符转换的问题
- 结构体中经常碰到的一个错误 undeclared identifier
- 编码中碰到的十个坑
- 编码中碰到的十个坑
- 编码中碰到的十个坑
- SQL中碰到的问题
- 工作中碰到的问题
- angularjs中碰到的问题
- js中碰到的问题
- HDMI输入分辨率转换碰到的问题
- myeclpse中生成javadoc时碰到编码GBK的不可映射字符问题
- 24 碰到的一个 idea的奇怪的编码问题
- 碰到个蛋疼的mysql编码问题 记录一下
- wap开发中碰到的问题(1)
- 【Visual C++】游戏开发笔记之八——基础动画显示(二)游戏循环的使用
- 关于pad、智能手机功能增进的设想
- 自定义实现struts2中的国际化机制
- ORA-12528: TNS: 监听程序: 所有适用例程都无法建立新连
- [c语言笔记]关于指针操作中使用异或交换两个变量的值
- 结构体编码转换中碰到的问题
- 【Visual C++】游戏开发笔记之十 基础动画显示(三) 透明动画的实现
- 【Visual C++】游戏开发笔记之十一 基础动画显示(四) 排序贴图
- 设计模式六大原则(2):里氏替换原则
- 基于自定义属性的Web客户端统一验证JavaScript函数库组件(ChkInputs)概述
- cookies
- 【Visual C++】游戏开发笔记十二 游戏输入消息处理(一) 键盘消息处理
- ubuntu最常用的10个快捷键
- b面试d