美好的一天,
我遇到了一些麻烦.我试图通过网络将字符数组发送到服务器.
这是我的代码:
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)
谢谢
实际上,该程序正在完成你告诉它要做的事情.它发送两个字符; 即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(...)将尝试print在PrintWriterAPI 上调用方法.但是哪一个?那么你提供了一个声明类型为的参数byte[].这将导致你打电话print(Object).
但等一下......怎么PrintWriter.print(Object)办?那么第一件事就是调用toString()参数.
这有什么作用?好了,因为对象是a byte[],这会调用由toString()提供的默认方法java.lang.Object.这给你一个字符串,看起来像B[@xxxxxxxx这里[B是"类名"为一个字节数组,序列xs是数组对象的身份哈希码的十六进制表示!
然后输出那个 String.
看到你的2个字节(实际上是字符)变成了11个字节.