Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 490|回复: 0

java 和 C++ Socket通信(java作为服务端server,C++作为客户端client,解决中文乱码问题GBK和UTF8)

[复制链接]
  • TA的每日心情
    奋斗
    2024-9-22 15:19
  • 签到天数: 795 天

    [LV.10]以坛为家III

    2050

    主题

    2108

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    724084
    发表于 2021-7-2 17:12:30 | 显示全部楼层 |阅读模式

     

    原文链接: http://www.cnblogs.com/kenkofox/archive/2010/04/25/1719649.html

     

    代码:

    http://files.cnblogs.com/kenkofox/Client-CPlusPlus.rar
    http://files.cnblogs.com/kenkofox/Server_Java.rar

     

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

     

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

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

     

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

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

     

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

     

    //获得输出输出流
    out = newPrintStream(clientSocket.getOutputStream());
     out.print(test);//直接UTF8输出,最终底层每个中文用3个字节传输
     out.print(newString(test.getBytes(),"GBK"));//转GBK失败,实际每个中文字用了4到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定义了一个异常。

     

     

    kenkofox@qq.com https://github.com/kenkozheng
     
     
     
     

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-10-8 05:51 , Processed in 0.063135 second(s), 27 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表