JAVA与C++用socket通讯出现中文乱码

java接收C++数据出现中文乱码:

将java这边的socket编码改为GBK就行了!

 

java和C++使用Socket通信,其实底层Socket都是相通的,所以只需要按照各自的语法去做就是了。

 

java服务器端使用ServerSocket的accept创建Socket,跟普通java之间的通信一致。

C++客户端使用makeConnect(server, port, "tcp"),send,recv等函数。

 

自己在这次编程中,首先遇到的是虽然连接成功了,但java无法接收C++发来的消息。

可能是用错函数之类的,后边改为下边的代码接收就没事了。

复制代码
  
  
1 1 // 接受数据,但不允许有中文,因为会乱码 2   2 DataInputStream in = new DataInputStream(clientSocket.getInputStream()); 3   3 byte [] buffer = new byte [ 10000 ]; // 缓冲区的大小 4   4 in.read(buffer); // 处理接收到的报文,转换成字符串 5   5 /** 6 6 * C++传递过来的中文字,需要转化一下。C++默认使用GBK。 7 7 * GB2312是GBK的子集,只有简体中文。因为数据库用GB2312,所以这里直接转为GB2312 8 8 * */ 9   9 message = new String(buffer, " GB2312 " ).trim();
复制代码

 

 

另外

最大的问题是字符的编码问题,如果发现java接收到的字符串是乱码,就要仔细看看接下来的说明了。

 

Java代码在运行时,默认用UTF8来处理字符串,Socket发送字符串(如果用高层输出流直接输出String的话,最后还是自动用UTF8方式把字符串拆分成byte数组再传输的。(可以见http://www.cnblogs.com/kenkofox/archive/2010/04/23/1719009.html

而C++在xp运行的时候默认使用GBK来传输Socket。

 

所以java接收到C++消息的时候,应该转为GBK或者GB2312,才能显示正确中文。

而C++要接收到正确的java消息,就要在java发送的时候转为GBK或者GB2312编码(因为C++转码比java麻烦很多嘛,哈哈)

 

  
  
1 byte [] responseBuffer = newClientRequestHandler(message).response().getBytes( " GB2312 " ); 2 out.write(responseBuffer, 0 ,responseBuffer.length);

 

 

而C++接收方面,只需要用buf装起来,然后转为string就是了。正确显示……代码大概是:

charCount = recv(socket, buf, len, 0);

string resultString(buf);

 

另外为了更好理解上述的编码问题,大家在java端发送信息到C++端的时候,试试下边的方式试试,很有意思的。记得要在C++那边关注charCount。  

复制代码
  
  
1 // 获得输出输出流 2 out = newPrintStream(clientSocket.getOutputStream()); 3   out.print(test); // 直接UTF8输出,最终底层每个中文用3个字节传输 4   out.print(newString(test.getBytes(), " GBK " )); // 转GBK失败,实际每个中文字用了4到5个字节传递 5   out.print(newString(test.getBytes( " GBK " ), " GBK " )); // 转GBK,但底层还是要拆成字节数组,当然最终还是跟UTF8一样
复制代码

 

 

 

接下来是完整的代码说明

java方面:

EchoServerThread是一个Server类,专门等待客户的连接,然后建立EchoThread进行处理。

EchoThread是一个处理消息的线程,主要包括接收消息和发送消息的socket操作。

ClientRequestHandler是处理字符串的实际业务逻辑类……

 

C++方面:

client.cpp是测试的主函数。 

SocketManager.h包含SocketManager类,简单封装了Socket的启动和发送等操作。

connection.h包含Connection类,封装了Socket的底层调用。

conn_exception.h定义了一个异常。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++中实现socket通讯需要使用操作系统提供的socket API。下面是一个简单的例子,展示了如何创建一个TCP服务器和一个TCP客户端进行通讯。 服务器端代码: ```cpp #include <iostream> #include <winsock2.h> using namespace std; int main() { // 初始化Winsock库 WSADATA wsaData; int result = WSAStartup(MAKEWORD(2, 2), &wsaData); if (result != 0) { cout << "WSAStartup failed: " << result << endl; return 1; } // 创建socket SOCKET listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (listenSocket == INVALID_SOCKET) { cout << "socket failed: " << WSAGetLastError() << endl; WSACleanup(); return 1; } // 绑定socket到本地IP和端口 sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(12345); addr.sin_addr.s_addr = INADDR_ANY; result = bind(listenSocket, (sockaddr*)&addr, sizeof(addr)); if (result == SOCKET_ERROR) { cout << "bind failed: " << WSAGetLastError() << endl; closesocket(listenSocket); WSACleanup(); return 1; } // 监听socket result = listen(listenSocket, SOMAXCONN); if (result == SOCKET_ERROR) { cout << "listen failed: " << WSAGetLastError() << endl; closesocket(listenSocket); WSACleanup(); return 1; } // 接受客户端连接 sockaddr_in clientAddr; int clientAddrSize = sizeof(clientAddr); SOCKET clientSocket = accept(listenSocket, (sockaddr*)&clientAddr, &clientAddrSize); if (clientSocket == INVALID_SOCKET) { cout << "accept failed: " << WSAGetLastError() << endl; closesocket(listenSocket); WSACleanup(); return 1; } // 从客户端接收数据 char buffer[1024]; result = recv(clientSocket, buffer, sizeof(buffer), 0); if (result == SOCKET_ERROR) { cout << "recv failed: " << WSAGetLastError() << endl; closesocket(clientSocket); closesocket(listenSocket); WSACleanup(); return 1; } // 处理客户端发送的数据 cout << "Received from client: " << buffer << endl; // 关闭socket closesocket(clientSocket); closesocket(listenSocket); WSACleanup(); return 0; } ``` 客户端代码: ```cpp #include <iostream> #include <winsock2.h> using namespace std; int main() { // 初始化Winsock库 WSADATA wsaData; int result = WSAStartup(MAKEWORD(2, 2), &wsaData); if (result != 0) { cout << "WSAStartup failed: " << result << endl; return 1; } // 创建socket SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (clientSocket == INVALID_SOCKET) { cout << "socket failed: " << WSAGetLastError() << endl; WSACleanup(); return 1; } // 连接服务器 sockaddr_in serverAddr; serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(12345); serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); result = connect(clientSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)); if (result == SOCKET_ERROR) { cout << "connect failed: " << WSAGetLastError() << endl; closesocket(clientSocket); WSACleanup(); return 1; } // 发送数据到服务器 const char* message = "Hello, server!"; result = send(clientSocket, message, strlen(message), 0); if (result == SOCKET_ERROR) { cout << "send failed: " << WSAGetLastError() << endl; closesocket(clientSocket); WSACleanup(); return 1; } // 关闭socket closesocket(clientSocket); WSACleanup(); return 0; } ``` 在Windows环境下编译运行上述代码,即可实现简单的socket通讯

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值