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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • linux修改smb端口_sftp默认端口号是多少

    linux修改smb端口_sftp默认端口号是多少本文介绍如何在Linux操作系统中更改默认的SFTP端口,支持Ubuntu、CentOS等发行版,同时还将向您展示如何配置防火墙以允许在新端口上使用。先声明的一点是不要将SFTP与FTPS混淆,因为两种协议具有相同的目的,FTPS代表FTPSecure,它是对标准FTP协议的扩展,支持TLS。简介SFTP(SSH文件传输协议)是一种安全文件协议,用于通过加密连接在两个主机之间传输文件,它还允许您…

    2022年9月14日
    1
  • CentOS 7 下使用yum安装MySQL5.7.20 最简单 图文详解

    CentOS 7 下使用yum安装MySQL5.7.20 最简单 图文详解CentOS7默认数据库是mariadb,但是好多用的都是mysql,但是CentOS7的yum源中默认好像是没有mysql的。上一篇安装的是5.6的但是我想安装5.7的yum安装是最简单的尝试过编译安装各种问题,最后就决定用yum。(经过一段时间的学习又写了一篇用源码安装mysql5.7.22的点击打开链接)1.卸载先停掉mysql进程没有安装过的可以直接跳过…

    2022年6月11日
    28
  • 免费拿走Vivado2017.4安装包及其license(附带安装教程)

    免费拿走Vivado2017.4安装包及其license(附带安装教程)免费拿走Vivado2017.4安装包及其license(附带安装教程)安装包下载地址:添加链接描述license:在文尾。。。安装教程:1.双击安装包文件夹中的xsetup文件2.运行安装:点击next。。3.三个IAgree都选上。。4.选择第二个,包含VIVADO设计的所有部件。。5.选择功能,一般选默认就好。。6.选择安装路径,保证容量足够即可,路径名不要出现非法字符。。7.点击Install,开始安装。。8.开始后,等几分钟,中间会跳出一两个安装确认,都点

    2022年7月26日
    90
  • SSH加密代理「建议收藏」

    SSH加密代理「建议收藏」1.首先拷贝putty到系统目录下2.然后执行命令putty-D22bin@ipplinkusername@hostname-D127.0.0.1:80883.设置代理就ok了

    2022年9月10日
    0
  • AVC1与H264的差别

    AVC1与H264的差别

    2021年11月30日
    52
  • 通过CLOVER 引导Windows与Linux双系统

    #什么是CLOVER可能有些朋友对CLOVER还不了解,因为有很多大神已经做过介绍,我这就做个引用吧。黑苹果引导工具Clover配置详解(转自[三个表哥])#为什么是CLOVER引导?自从折腾过黑苹果后,深深被四叶草的个性化界面以及灵活设置给吸引了。然而并不是长期会有使用黑苹果的需求,以及公司的电脑只用Win10+Ubuntu双系统,虽然是正常使用,但,界面不好看呀!!作为一…

    2022年4月7日
    68

发表回复

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

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