首页 > 代码库 > CSocket编程中字符乱码问题

CSocket编程中字符乱码问题

 

<style></style>

CSocket编程中字符乱码问题

首先把自己在编程调试中遇到的这个字符乱码问题简单的阐述一下:

  • 平台:Windows8.1 + VS2010;
  • 使用MFC自带的CSocket;
  • Server与Client之间属于TCP连接,

Server向Client发送消息,其形式为结构体,定义如下:

typedef struct message{    int seq;    char name[10];    char time[24];}Msg;

其中seq直接赋值,name变量的填充使用 strcpy() 函数从CString所转变的字符指针复制而来,其长度一般为4~6,肯定不会超过10。然而time变量也是使用strcpy()函数赋值而来,其所复制的字符串长度刚刚是24,也就是说char time数组没有结束标志位。我当时没有想太多,本着节约的原则,就把这个数据包发送出去了,代码如下

//Server端Msg msg;msg.seq = 10;strcpy(msg.name, pname);strcpy(msg,time, ptime);if(!socket_server.Send((char*)&msg, sizeof(Msg), 0)){    ...}  //Client端Msg msg;if(!socket_client.Receive((char*)&msg, sizeof(Msg), 0)){    ...}CString strmsg(msg.time);AfxMessageBox(strmsg);      //这里显示的信息除了正确的一部分,后面总是有乱码

结果Client收到的time变量除了能够恢复出原始的数据之外,其后面总是有一串乱码。错误现象如下:

技术分享

为了这个问题调试测试了许久,其实原因很简单,就是发送的字符数组没有带结束标志位,现在把测试的结果总结出来,为了把问题简化,测试的时候通信双方都是发送接收字符数组类型,结构体类型其实类似。

1. 发送方字符数组比字符串长度大

这个就是最常见的情况了,肯定不会出现乱码的,其代码如下:

char buf[20] = "I send a message";socket_server.Send(buf, 20, 0);

字符串长度为16,比数组长度小,如果接收方同样以20长的buf来接收,是不会产生乱码的。

2. 发送方恰好发送字符串长度的字符数组

这种情况就是为了要验证出现乱码到底是不是由于字符数组没有带结束标志位,其代买如下:

char buf[] = "I send you a message";socket_server.Send(buf, 20, 0);

上面的这种情况,字符串长度刚好为20,并且发送的长度也为20,就是说只是把所有的字符发送出去了,当接收方接收数据时,以大于等于20的buf,这个时候是会出现乱码的。

3. 接收方的buf刚刚等于字符串长度

这种情况是想看看,当发送方正确发送数据的前提下,接收方没有正确的设置好buf的大小而导致的不能够接收字符串的结束标志位所产生的结果是什么,其代码如下:

//Server端char buf[25] = "I send you a message";socket_server.Send(buf, 25, 0);//Client端char buf[20];socket_client.Receive(buf, 20, 0);

由于字符串的长度就是为20,所以接收方是接收不到那个结束的标志位的,这种情况也会产生乱码。

4. 总结

简而言之,对于char 数组类型,发送方必须发送其结束标志位,而接收方也必须接收其结束标志位。如果上面两种情况之一得不到满足,是肯定会产生乱码的。把这些记录下来,希望下次不要犯这么低级的错误(--!)

从现象来看,接收方从结束数据到赋值给你定义好的buf的时候,肯定那个指针多指向了一块内存区域。但是为什么会这样呢??到底计算机在运行的过程中是哪个环节导致了出现了上述的现象呢??还是需要更加仔细的研究的。

 

CSocket编程中字符乱码问题