qq_29022421
qq_29022421
2020-09-11 09:30
采纳率: 100%
浏览 475
已采纳

java netty与c++使用socket tcp协议通信,c++作为客户端,java作为服务端使用的是netty,接收字节数据,先将字节转16进制字符串再转为普通字符串,中英文全出现乱码。求急大神,谢谢!

通过重写channelRead(ChannelHandler ctx, Object msg) 方法读取c++发过来的字节数据。

public class ServerHandler extends ChannelHandlerAdapter{

public void channelRead(ChannelHandlerContext channel, Object msg) throws Exception {
    try {
        ByteBuf buf = (ByteBuf)msg;
        byte [] bytes = new byte[buf.readableBytes()];
        buf.readBytes(bytes);//复制内容到字节数组bytes 
        String hex = bytes2HexString(bs); //将byte数组转为16进制字符串

String str = hexString2String(hex,"GBK"); //将16进制字符串转换为普通字符串
System.out.println(str); //这里打印全是乱码
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
log.error("异常:",e);
}
}

private String bytes2HexString(byte[] b) {  
    StringBuffer result = new StringBuffer();  
    String hex;  
    for (int i = 0; i < b.length; i++) {  
        hex = Integer.toHexString(b[i] & 0xFF);  
        if (hex.length() == 1) {  
            hex = '0' + hex;  
        }  
        result.append(hex.toUpperCase());  
    }  
    return result.toString();  
}

    private String hexString2String(Stirng hex, String charset) {
        byte[] bs = new byte[hex.length()/2];
        for(int i=0; i<bs.length; i++) {
            bs[i] = (byte)(0xff&Integer.parseInt(hex.substring(i*2,i*2+2),16));
        }
        try{
        hex = new String(bs, charset);
        }catch(Exception e) {
            e.printStackTrace();
        }
        return hex;
    }   

}

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

6条回答 默认 最新

  • wd369
    wd369 2020-09-12 19:26
    已采纳

    要判定问题出在哪里。 你可以先测试两端传送是否正常,用base64 encode/decode 来代替hexString2String功能函数,看看是否网络数据传送代码有问题。如果没有问题,那就是编码解码问题,需要检查hexString2String 是否有问题。
    也可以先测试hexString2String,选一些实验数据,分别用Java、C把这些函数产生输出输入,看看结果是否正常。

    点赞 评论
  • dabocaiqq
    dabocaiqq 2020-09-11 09:32

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

    点赞 评论
  • qq_42024009
    风丶飞 2020-09-11 09:34

    确定一下2边的字符的编码是否一样,java默认是UTF-8 c++是GBK

    不清楚装换可以看下https://www.cnblogs.com/kenkofox/archive/2010/04/25/1719649.html

    点赞 评论
  • shuangmu9768
    shuangmu9768 2020-09-11 10:12

    1.先试下传输字母看乱码不乱
    2.看下C++的编码是否为GBK
    3.数据结构检查下,看接口是否完整
    4.看下网络传输时大小端是否一致。

    点赞 评论
  • u013202238
    brucelwl 2020-11-18 16:09

    两边协议要一直,注意编解码

    点赞 评论
  • weixin_45877245
    呆呆猿 2021-08-02 14:00

    我的也是Java服务端使用netty,c++作为客户端,传输数据的时候服务器接受的是乱码,但是使用gbk编码集中文最后的可以输出来,其他的全是乱码,感觉和字节序有关

    点赞 评论

相关推荐