通过tcp发送的值大于127的Java字符

Zap*_*ica 1 java arrays char

美好的一天,

我遇到了一些麻烦.我试图通过网络将字符数组发送到服务器.

这是我的代码:

char[] arr= {3,4};    
public void sendMessage(String message){
    if (out != null && !out.checkError()) {
        out.print(arr);
        out.flush();
    }
}
Run Code Online (Sandbox Code Playgroud)

当我运行它时,lanshark检测到它收到了一个包含2个字节数据的数据包.好的一切都很好.

现在当我运行这个:

 char[] arr= {3,160};      // notice 160 *****
public void sendMessage(String message){
    if (out != null && !out.checkError()) {
        out.print(arr);
        out.flush();
    }
}
Run Code Online (Sandbox Code Playgroud)

lanshark说数据包有3个字节的数据?确切的数据是:

03 c2 a0

现在为什么要在那里添加c2?我知道它与我的char大于127这一事实有关.但我需要发送这个160的值.

请你帮帮我.我是否需要使用其他类型的数据,或以不同的方式发送?我知道你可以在C中做到这一点.我怎么能在java中做到这一点?

这是我的out对象的代码:

PrintWriter out;
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
Run Code Online (Sandbox Code Playgroud)

谢谢

Ste*_*n C 5

实际上,该程序正在完成你告诉它要做的事情.它发送两个字符; 即unicode codepoints 3(\u0003)和160(\u00a0).这些字符使用您平台的默认字符编码进行编码...它似乎是UTF-8.字节c2 a0\u00a0字符的UTF-8编码.

但你实际上要做的是发送2个字节.

在Java中char是16位类型,而不是8位类型.如果要发送8位值,则需要使用该byte类型.

您正在犯的另一个错误是您尝试使用a发送(基本上)二进制数据Writer.该Writer接口用于(16位)面向字符的数据.你应该使用OutputStreamAPI ...

无论如何......这是一个代码片段,用于说明如何发送字节数组;

byte[] arr = new byte[]{3, (byte) 160);
OutputStream out = socket.getOutputStream();
out.write(arr);
Run Code Online (Sandbox Code Playgroud)

我现在改为现在,"out.print(new String(arr).getBytes(Charset.forName("UTF-8")));"这是我在wireshark上获得的数据:11字节:5b42403431653230396538它还应该是2个字节?

你让它变得更糟!

让我们分开:

  • new String(arr) 给你一个2个字符的字符串.
  • .getBytes(...)将它转换为包含字节的3字节数组03 c2 a0.
  • out.print(...)将尝试printPrintWriterAPI 上调用方法.

但是哪一个?那么你提供了一个声明类型为的参数byte[].这将导致你打电话print(Object).

但等一下......怎么PrintWriter.print(Object)办?那么第一件事就是调用toString()参数.

这有什么作用?好了,因为对象是a byte[],这会调用由toString()提供的默认方法java.lang.Object.这给你一个字符串,看起来像B[@xxxxxxxx这里[B是"类名"为一个字节数组,序列xs是数组对象的身份哈希码的十六进制表示!

然后输出那个 String.

看到你的2个字节(实际上是字符)变成了11个字节.