我正在尝试将十六进制消息从C服务器传递到Java客户端。 通讯正常。但是我在Java客户端上获得的十六进制值似乎附加了“ ff”。为什么会这样?

在C端,当我打印要发送的字节(以十六进制表示)时,它们似乎没问题。

请参见下面的代码:

C服务器: 通用标签

Java客户端: 通用标签

输出: len的值= -36 缓冲区[5]= 0 缓冲区[6]= 0xfffffffdc

已更新

这是我的Wireshark输出(这是C服务器推送到Java Client的内容):

请注意,在第5行,“ 00 dc”对应于datalen= 220,应将其存储在Java客户端上的len中。因此,Java客户端上显然存在一些错误。就像您提到的一样,我可以使用Integer.toHexString((((int)buffer [index])&0xFF)进行打印。但是我需要用正确的十六进制值存储字节数组。请帮忙 通用标签

有帮助吗?

解决方案

在这种情况下,您的第一步应该是查看“通过电线”发送的内容。如果可以,请考虑使用 wireshark tcpdump 来查看正在传输的内容。这样,您可以找出无法正常工作的情况。两者都可以监视绑定到本地IP的套接字以及环回套接字。

但是从表面上看,我同意正在进行签名/未签名的冲突。

如果有此输出,则有助于确定“谁”出了错。

更新

如前所述,您将希望屏蔽掉并仅使用最低的8位,这可以通过以下方式完成: 通用标签

您可以通过两种方式将其引入代码中,一种是通过简单的静态函数,例如,您需要为每个字节调用 通用标签

另一个是DataInputStream.read()的包装函数,该函数会将字节读入缓冲区,然后将其全部屏蔽。看起来可能像这样: 通用标签

如果选择第一种方法,则需要在使用的任何buffer []值上调用mask()。所以 通用标签

将会 通用标签

如果选择第二种方法,则将缓冲区从字节类型的数组更改为int: 通用标签

并可以将while循环更新为: 通用标签

话虽如此...

比以上任何一种方法更好的选择是利用 DataInputStream的readUnsignedByte方法

您需要自己一次从流中提取40个字节,但要清楚一点,而不是花哨的时间。我认为这将是首选方法。

其他提示

java中的字节已签名。因此,每个具有最高有效位设置的值都是一个负值。当将其转换为整数时(调用Integer.toHexString时会发生这种情况),符号将被扩展。因此,如果它是10000000b,它将变成11111111111111111111111111110000000b或0xFFFFFF80而不是0x80。因为那是32位相同的负值。 通用标签

应该修复它。

顺便说一句,java没有无符号类型。

通用标签

Integer.toHexString(buffer[index] & 0xFF )将解决您的问题。

听起来像符号位传播。len和其他JAVA变量看起来不应该像带符号一样。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top