我发送的UDP数据报只有一个字符串作为内容,我正在创建这样的数据包:
String content = ALIVE + "," + clusterName + "," + nodeName + "," + location;
byte[] data = content.getBytes();
packet = new DatagramPacket(data, data.length);
问题是,当它到达时,它最后有一些奇怪的二进制数据,不能显示为字符(在Sublime Text中它只显示几个NUL符号)。
String data = new String(packet.getData());
我使用字符串标记器(,)提取不同的信息部分,现在通过在发送之前添加另一个来解决此问题。我仍然想知道,这些数据来自哪里?
答案 0 :(得分:1)
永远不要打电话给String.getBytes()
或刚刚接过byte[]
的构造函数。
始终在两边传递明确的字符集。
由于您的代码当前已编写,发件人可以生成一个编码的字节,并且读者可以(错误地)将它们解释为其他编码,从而产生各种风格的垃圾。
您可能还有其他问题。
答案 1 :(得分:1)
您在一端将字符转换为字节,而在另一端从字节转换为字符。一切都很好,但你没有指定正在使用的字符编码,如果它们不匹配,字节/字符转换将不正常工作。
您有两种选择:
-Dfile.encoding
JVM参数强制执行JVM使用的默认编码。我更喜欢第一个选项,因为您可能无法控制代码的执行方式或位置(例如,如果您的代码被提升到库中以供其他地方使用)
答案 2 :(得分:1)
您可以像这样明确指定字符集:
byte[] data = content.getBytes(StandardCharsets.UTF_8);
答案 3 :(得分:1)
请仔细注意答案,建议您在两端明确指定字符编码。他们的建议非常好。
但是,如果准确接收到字符数据但最后添加了一些垃圾,那么您的问题不太可能是由于字符编码不匹配引起的。更有可能的原因是接收者错误地使用了DatagramPacket
。
DatagramPacket
为消息提供固定长度的缓冲区,getData()
方法返回该缓冲区。如果它比最近收到的消息长,那么尾端将包含与该消息无关的数据。收到消息后,必须使用数据包的getLength()
方法确定缓冲区中有多少字节对应于消息。