java c++ socket 中文乱码解决「建议收藏」

java c++ socket 中文乱码解决「建议收藏」java服务器端使用ServerSocket的accept创建Socket,跟普通java之间的通信一致。C++客户端使用makeConnect(server,port,”tcp”),send,recv等函数。 自己在这次编程中,首先遇到的是虽然连接成功了,但java无法接收C++发来的消息。可能是用错函数之类的,后边改为下边的代码接收就没事了。

大家好,又见面了,我是你们的朋友全栈君。

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定义了一个异常。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/158731.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 归并排序算法详细图解_归并排序算法详解

    归并排序算法详细图解_归并排序算法详解一、什么是归并排序1.概念归并排序(Mergesort)是建立在归并操作上的一种有效的排序算法,归并排序对序列的元素进行逐层折半分组,然后从最小分组开始比较排序,合并成一个大的分组,逐层进行,最终所有的元素都是有序的2.算法原理这是一个无序数列:4、5、8、1、7、2、6、3,我们要将它按从小到大排序。按照归并排序的思想,我们要把序列逐层进行拆分序列逐层拆分如下然后从下往上逐层合并,首先对第一层序列1(只包含元素4)和序列2(只包含元素5)进行合并创建一个大序列,序列长度为两个小序列长度

    2022年10月20日
    2
  • kill命令杀死所有进程_linux 杀死进程

    kill命令杀死所有进程_linux 杀死进程1kill:根据进程号(PID)杀死进程在linux上,一般常用的杀死进程的命令是kill,但是也有缺陷,下面说1、查看指定名称的进程,如下我查看运行python程序的进程pythonaux|greppython2、根据进程号(PID)杀死进程:第二列显示的就是进程号killPID3、强制杀死进程,有些进程可能杀不死,就加个-9参数,强制让它死掉!kill-9PID5、杀死多个进程,在后面跟多个进程的PID号即可kill-9PID1PID2PID3…

    2025年7月10日
    3
  • shell编程100例「建议收藏」

    shell编程100例「建议收藏」1、编写helloworld脚本#!/bin/bash#编写helloworld脚本echo”HelloWorld!”2、通过位置变量创建Linux系统账户及密码#!/bin/bash#通过位置变量创建Linux系统账户及密码#$1是执行脚本的第一个参数,$2是执行脚本的第二个参数useradd”$1″echo”$2″|…

    2022年7月16日
    15
  • CNN做时间序列预测_lstm时间序列预测_2「建议收藏」

    此数据是1949到1960一共12年,每年12个月的航班乘客数据,一共144个数据,单位是1000。我们使用它来进行LSTM时间序列预测的实验。数据如图所示第一列为时间第二列为数据编写代码头文件importnumpyimportmatplotlib.pyplotaspltfromkeras.modelsimportSequentialfromkeras….

    2022年4月8日
    175
  • 在centos服务器安装MySQL数据库详细步骤

    在centos服务器安装MySQL数据库详细步骤

    2021年9月26日
    65
  • 远线程注入

    远线程注入OpenProcess函数打开现有的本地进程对象。HANDLEWINAPIOpenProcess(_In_DWORDdwDesiredAccess,_In_BOOLb

    2021年12月13日
    46

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号