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

代码:

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 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 条评论
登录 后参与评论

相关文章

来自专栏逸鹏说道

在 ASP.NET MVC 中使用异步控制器

可以通过 AsyncController 类编写异步操作方法。 可以对长时间运行的、非 CPU 绑定的请求使用异步操作方法。 这样可避免在处理请求时阻塞 Web...

35611
来自专栏决胜机器学习

PHP开发过程的那些坑(四) ——PDO bindParam函数

PHP开发过程的那些坑(四)——PDO bindParam函数 (原创内容,转载请注明来源,谢谢) 坑: bindParam是PDOStatement的一个方法...

3346
来自专栏流柯技术学院

TestNG官方文档中文版(4)-运行TestNG

4 - 运行TestNG TestNG可以以不同的方式调用:     * Command line     * ant     * Eclips...

1152
来自专栏编程

Java并发编程:概念和原理

. Java并发编程在实际的工作中应用广泛,有时候需要通过多线程去异步做一些事情,有时候需要通过多线程提升一个任务执行的效率。最近又在回顾一些Java编程的基本...

1966
来自专栏二进制文集

Struts1 和 Struts2 对比

参考链接:http://blog.csdn.net/john2522/article/details/7436307

862
来自专栏雪胖纸的玩蛇日常

老男孩Python全栈开发(92天全)视频教程 自学笔记18

2034
来自专栏orientlu

python 配置文件读写

将代码中的配置项抽取到配置文件中,修改配置时不需要涉及到代码修改,避免面对一堆令人抓狂的 magic number,极大的方便后期软件的维护。

3483
来自专栏主机笔记

centos安装ab工具给网站进行压力测试

在配置好网站服务器后,我们可以进行压力测试看一看实际环境中的效果怎么样,判断服务器质量、网站程序设计是否合理、提前预防突发事件。今天就介绍一款开源免费的压力测试...

27210
来自专栏cmazxiaoma的架构师之路

电商毕业设计小节2

1776
来自专栏coolblog.xyz技术专栏

MyBatis 源码分析 - 内置数据源

本篇文章将向大家介绍 MyBatis 内置数据源的实现逻辑。搞懂这些数据源的实现,可使大家对数据源有更深入的认识。同时在配置这些数据源时,也会更清楚每种属性的意...

941

扫码关注云+社区