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

时间:2013-01-30 12:58:19

标签: java arrays char

美好的一天,

我遇到了一些麻烦。我正在尝试通过网络将字符数组发送到服务器。

这是我的代码:

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

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

现在我跑这个:

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

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

  

03 c2 a0

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

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

这是我的out对象的代码:

PrintWriter out;
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);

由于

4 个答案:

答案 0 :(得分:5)

事实上,该程序完全按照你的要求去做。它发送两个字符;即unicode代码点3\u0003)和160\u00a0)。这些字符使用您平台的默认字符编码进行编码...它似乎是UTF-8。字节c2 a0\u00a0字符的UTF-8编码。

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

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

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

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

byte[] arr = new byte[]{3, (byte) 160);
OutputStream out = socket.getOutputStream();
out.write(arr);

  

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

你让事情变得更糟!

让我们分开:

  • new String(arr)为您提供2个字符的字符串。
  • .getBytes(...)会将其转换为包含字节03 c2 a0的3字节数组。
  • out.print(...)会尝试在print API上调用PrintWriter方法。

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

但是等一下...... PrintWriter.print(Object)做了什么?那么第一件事就是在论证上调用toString()

这是做什么的?由于对象是byte[],因此调用toString()提供的默认java.lang.Object方法。这会给你一个看起来像B[@xxxxxxxx的字符串,其中[B是"类名"对于字节数组,x s的序列是数组对象的标识哈希码的十六进制表示!

然后输出 String。

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

答案 1 :(得分:4)

你没有告诉我们关于out的任何信息 - 甚至不是类型 - 但我强烈怀疑它使用UTF-8来编码你的角色数据。 U + 00A0(即字符160)在UTF-8中被编码为0xc2 0xa0。

如果您同时控制读写代码,使用UTF-8几乎肯定是最佳事情:这意味着您可以使用整个Unicode。如果您使用的是ISO-8859-1(我怀疑您希望使用它 - 每个字符一个字节,对于所有字符),您将仅限于[U + 0000,U + 00FF]范围。

答案 2 :(得分:0)

您可以按照以下步骤将数据发送为“UTF-8”:

out.print(new String(arr).getBytes(Charset.forName("UTF-8"));

此外,您还必须使用UTF-8编码创建输出流,如下所示:

out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF-8")), true);

现在您将发送用UTF-8编码的char数组,每个字符最多8个字节(最大值为256)。请参阅@JonSkeet的答案,了解为什么需要“UTF-8”编码。

答案 3 :(得分:0)

确保输入和输出采用相同的编码,然后您将得到您想要的内容。例如,

发送时

 mPrintWriterClient = new PrintWriter(new BufferedWriter(new    OutputStreamWriter(mSocket.getOutputStream(), "UTF-8")), true);     

接收时

 mBufferedReaderClient = new BufferedReader(new InputStreamReader(mSocket.getInputStream(), "UTF-8"));