将从 Python UDP 流接收的字符串与 Java 字符串进行比较

Posted

技术标签:

【中文标题】将从 Python UDP 流接收的字符串与 Java 字符串进行比较【英文标题】:Comparing String received from Python UDP Stream to a Java String 【发布时间】:2011-06-18 22:25:39 【问题描述】:

我目前正在使用 SocketServer 类用 Python 编写的服务器和使用 DatagramSocket 和 DatagramPacket 类用 Java 编写的客户端之间进行 UDP 通信试验。 服务器接受 python 方法调用作为输入,并将 stdout 和 stderr 路由回客户端,以 1024 字节大小的数据包传输。

通信正常,客户端可以从服务器接收数据包并向其发送数据包,但是在比较数据时遇到了问题。

例如,当在客户端接收到包含字符串__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

似乎数据包中的字符串包含我要比较的字节以及 1024 字节数据包中的其他字节,这就是 String.equals() 方法总是返回 false 的原因。

在从字节数组转换为字符串时,有没有办法强制 Java 省略尾随零?

【问题讨论】:

【参考方案1】:

我现在通过指定偏移量0 和将数据包转换为字符串时的数据包长度来解决问题:

String(packet.getData(), 0, packet.getLength(), "UTF-8");

结果字符串被去掉了尾随的0s。

【讨论】:

【参考方案2】:

在我看来,您可以在packet.getData 之前使用setLength 来指定要从缓冲区获取多少字节。

http://download.oracle.com/javase/1.4.2/docs/api/java/net/DatagramPacket.html#setLength%28%29

【讨论】:

请考虑以下可能性:(0) OP 通常不知道他想要获得多少字节 (1) setLength 是 SENDER 可能想要做的事情 (2) RECEIVER(有问题的 Java 代码)可能想要使用 getLength (3),根据 OP,使用 getLength 很可能返回 1024【参考方案3】:

5f5f444f4e455f5fa 是奇数个十六进制字符。看起来应该是 5f5f444f4e455f5fa0 即"__DONE__\xA0" 而不是你写的"__DONE__"。如果不是,为什么传入的数据包中是 'a0'?

发送一个用 NUL 填充的 1024 字节数据包是不是有点浪费?也许您应该与数据包的来源交谈。

【讨论】:

哦,天哪,是的,感谢您的更正,消息确实以换行符结尾。我编辑了我原来的帖子。对不起! @JeanMarieStaub:您的帖子仍然不一致。 done 字符串的十六进制仍然有奇数个十六进制字符。您的数据包的十六进制输出显示a0(NO-BREAK SPACE)而不是0a(换行符)。请从实际输出中复制/粘贴,不要从内存中输入。 这两个十六进制表示实际上取自我的终端输出。我通过解析字符串的字节数组并将每个字节的format("%x", byte) 字符串相加来生成它们,这可能就是不一致的来源。除了第二个字符串的最后几百个 0 之外,我没有从输出中手动删除任何内容。至于您的第二个建议,我可能会研究一下,但是服务器代码不是我编写的,目前我只是想获得一个非常基本的实验版本来进行实验。 @JeanMarieStaub: aarrgghh (1) 尝试“%02x” [前导零,空格分隔符以确保易读性] (2) Java 没有相当于 Python 的 repr() 吗? [将***重新发明为一个多边的多边形不是一个好主意] 对不起,导致磨牙的错误,我只是在 Java 上迈出了第一步,这是一个快速而肮脏的 hack,因为我没有找到字符串的字节表示相当于 Java 中的 repr() (根据***.com/questions/1350397/…,它似乎不存在于标准库中)。虽然这不是那个特定错误的借口,但格式语法几乎与 Python 和 C 中的相同 :-) 更正后,输出确实是 5f5f444f4e455f5f0a,而不是之前的 [..]fa

以上是关于将从 Python UDP 流接收的字符串与 Java 字符串进行比较的主要内容,如果未能解决你的问题,请参考以下文章

TCP协议与UDP协议

TCP协议与UDP协议

Python UDP协议编程

Python UDP协议编程

如何通过python实现H.264视频推流与接收

python粘包分析与解决