【问题标题】:Comparing String received from Python UDP Stream to a Java String将从 Python UDP 流接收的字符串与 Java 字符串进行比较
【发布时间】: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 省略尾随零?

【问题讨论】:

    标签: java python character-encoding


    【解决方案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() (根据stackoverflow.com/questions/1350397/…,它似乎不存在于标准库中)。虽然这不是那个特定错误的借口,但格式语法几乎与 Python 和 C 中的相同 :-) 更正后,输出确实是 5f5f444f4e455f5f0a,而不是之前的 [..]fa
      猜你喜欢
      • 2017-02-20
      • 2010-10-06
      • 2012-08-31
      • 1970-01-01
      • 1970-01-01
      • 2021-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多