Java:为什么我的字符串会通过 UDP 损坏?
Java: Why does my String get corrupted over UDP?
我正在发送一个只有一个字符串作为内容的 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());
我使用字符串分词器 (,) 提取了不同的信息部分,现在只需在发送之前在末尾添加另一个 , 即可解决此问题。还是很想知道,这个数据是从哪里来的?
永远永远不要调用 String.getBytes()
或只接受 byte[]
的构造函数。
始终在两侧传递显式字符集。
按照您当前编写的代码,发送方可以生成一种编码的字节,而 reader 可以(误)将它们解释为其他编码,从而产生各种垃圾。
您可能还有其他问题。
您在一端从字符转换为字节,在另一端从字节转换为字符。一切都很好,但是您没有指定正在使用的字符编码,如果这些编码不匹配,byte/character 转换将 not 正常工作。
您有两个选择:
- 使用适当的字符集指定转换
- 使用名称容易混淆的
-Dfile.encoding
JVM 参数强制执行 JVM 使用的 默认 编码。
我更喜欢第一个选项,因为您可能无法控制代码的执行方式或位置(例如,如果您的代码被提升到库中以供其他地方使用)
您可以像这样明确指定字符集:
byte[] data = content.getBytes(StandardCharsets.UTF_8);
请仔细注意建议您在两端明确指定字符编码的答案。他们的建议很好。
但是,如果字符数据接收准确,但最后添加了一些垃圾,那么您的问题不太可能是由字符编码不匹配引起的。更有可能是由于接收方不正确地使用了 DatagramPacket
。
DatagramPacket
为消息提供固定长度的缓冲区,getData()
方法 returns 该缓冲区。如果它比其中最近收到的消息长,那么尾端将包含与该消息无关的数据。收到消息后,必须使用数据包的getLength()
方法来判断缓冲区中有多少字节对应消息。
我正在发送一个只有一个字符串作为内容的 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());
我使用字符串分词器 (,) 提取了不同的信息部分,现在只需在发送之前在末尾添加另一个 , 即可解决此问题。还是很想知道,这个数据是从哪里来的?
永远永远不要调用 String.getBytes()
或只接受 byte[]
的构造函数。
始终在两侧传递显式字符集。
按照您当前编写的代码,发送方可以生成一种编码的字节,而 reader 可以(误)将它们解释为其他编码,从而产生各种垃圾。
您可能还有其他问题。
您在一端从字符转换为字节,在另一端从字节转换为字符。一切都很好,但是您没有指定正在使用的字符编码,如果这些编码不匹配,byte/character 转换将 not 正常工作。
您有两个选择:
- 使用适当的字符集指定转换
- 使用名称容易混淆的
-Dfile.encoding
JVM 参数强制执行 JVM 使用的 默认 编码。
我更喜欢第一个选项,因为您可能无法控制代码的执行方式或位置(例如,如果您的代码被提升到库中以供其他地方使用)
您可以像这样明确指定字符集:
byte[] data = content.getBytes(StandardCharsets.UTF_8);
请仔细注意建议您在两端明确指定字符编码的答案。他们的建议很好。
但是,如果字符数据接收准确,但最后添加了一些垃圾,那么您的问题不太可能是由字符编码不匹配引起的。更有可能是由于接收方不正确地使用了 DatagramPacket
。
DatagramPacket
为消息提供固定长度的缓冲区,getData()
方法 returns 该缓冲区。如果它比其中最近收到的消息长,那么尾端将包含与该消息无关的数据。收到消息后,必须使用数据包的getLength()
方法来判断缓冲区中有多少字节对应消息。