如何在Java中存储无符号短整型?

3
通常我使用Netty和它的BigEndianHeapChannelBuffer在Java中接收无符号短整型(来自C++软件)。当我像这样做时: ``` buf.readUnsignedByte(); buf.readUnsignedByte(); ``` 它返回:149和00。到目前为止一切都很好。因为服务器将149作为无符号短整型[2个字节]发送。 相比之下,我想在重新启动应用程序后接收无符号短整型: ``` buf.readUnsignedShort(); ``` 神奇的事情发生了。它返回:38144。 下一步是检索无符号字节: ``` short type = buf.readUnsignedByte(); System.out.println(type); ``` 它返回:1,这是正确的输出。 有人能帮助我吗? 我深入调查了一下,这就是Netty对它所做的内容:
public short readShort() {
    checkReadableBytes(2);
    short v = getShort(readerIndex);
    readerIndex += 2;
    return v;
}

public int readUnsignedShort() {
    return readShort() & 0xFFFF;
}

但是我仍然无法弄清楚问题出在哪里。我只想能够读取那个149。


1
没有太多的魔法,149*256+0=38144。你已经指定了BigEndian,所以这是正确的,最高有效字节先被发送。 - Roger Lindsjö
你可能指的是“无符号短整型[2字节]”。 - User
短整型(shorts),无论是有符号还是无符号,都占用2个字节。而整型(ints)则占用4个字节。 - Louis Wasserman
@RogerLindsjö,你能再解释一下吗?为什么要乘以256? 我想我错过了一些关于二进制补码等方面的课程。 - mic-kul
1
@mickula 短整数(short)是由两个字节(byte)组成的,其中一个字节的值是另一个字节的256倍。因为你使用的是BigEndian,所以第一个字节的值更大。这类似于十进制数123的数字1、2和3。第一位的值是下一位的10倍,而下一位的值是下一位的10倍,以此类推。因此,当数字逐个传输时,1 * 100 + 2 * 10 + 3 = 123。如果你将1、2和3视为小端序,则应使用1 + 2 * 10 + 3 * 100 = 321。256是因为一个字节的大小是256。 - Roger Lindsjö
显示剩余3条评论
2个回答

1

您也可以借鉴Java DataInputStream.readUnsignedShort()的实现方式:

public final int readUnsignedShort() throws IOException {
    int ch1 = in.read();
    int ch2 = in.read();
    if ((ch1 | ch2) < 0)
        throw new EOFException();
    return (ch1 << 8) + (ch2 << 0);
}

0
答案是改变字节序。感谢在评论中写道的Roger:
“没有什么魔法,149*256+0=38144。你已经指定了BigEndian,所以这似乎是正确的,最重要的字节首先被发送。”
还有:
“@mickula短整型是两个字节,其中一个字节的价值是另一个字节的256倍,由于您使用BigEndian,第一个字节是价值更高的字节。类似于十进制数字123的数字1、2和3。第一个位置是比下一个位置高10倍的位置,而下一个位置是比下一个位置高10倍的位置,依此类推。因此,当数字逐个传输时,1 * 100 + 2 * 10 + 3 = 123。如果您将1、2和3视为小端,则会使用1 + 2 * 10 + 3 * 100 = 321。256是因为字节的大小为256。”
感谢他的评论,我只需通过添加以下内容在服务器引导程序中切换字节序:
bootstrap.setOption("child.bufferFactory", new HeapChannelBufferFactory(ByteOrder.LITTLE_ENDIAN));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接