我目前正在尝试使用SocketServer类在Python编写的服务器和使用DatagramSocket和DatagramPacket类用Java编写的客户端之间的UDP通信。 服务器接受python方法调用作为输入,并将stdout和stderr路由回客户端,以1024byte大小的数据包传输。
通信正在运行,客户端可以从服务器接收数据包并向其发送数据包,但是在比较数据时我遇到了问题。
例如,当在客户端中接收包含字符串__DONE__\n
的数据包时,使用System.out.print(packet.getData())
打印正常。当我尝试将它与String done = "__DONE__\n"
进行比较时,我只会遇到问题,如下所示:
while (String(packet.getData()).equals(done) != true) {
doStuff();
}
这里循环永远运行,因为被计算的语句总是返回false
。
我的猜测是它与不同的编码有关。我试图比较数据包中的字符串和本机Java字符串的字节数组,并得到以下结果:
String done: 5f5f444f4e455f5f0a
String(packet.getData()): 5f5f444f4e455f5fa0000000[...]
// The 0s are repeated for the whole 1024bytes of the packet
似乎来自datapacket的String包含我要比较的字节以及1024byte数据包中的其他字节,这就是String.equals()方法总是返回false的原因。
有没有办法强制Java在从字节数组转换为字符串时省略尾随零?
答案 0 :(得分:2)
我现在设法通过在将数据包转换为字符串时指定0
的偏移量和数据包的长度来解决问题:
String(packet.getData(), 0, packet.getLength(), "UTF-8");
生成的字符串将被删除尾随的0
。
答案 1 :(得分:0)
在我看来,你可以在setLength
之前使用packet.getData
来指定你想从缓冲区中获取多少字节。
http://download.oracle.com/javase/1.4.2/docs/api/java/net/DatagramPacket.html#setLength%28%29
答案 2 :(得分:0)
5f5f444f4e455f5fa是十六进制字符的ODD数。看起来它应该是5f5f444f4e455f5fa0,即"__DONE__\xA0"
,而不是你写的"__DONE__"
。如果没有,为什么传入数据包中的'a0'?
不发送用NUL填充的1024字节数据包有点浪费吗?也许您应该与数据包的来源进行对话。