PacketInputStream 不向前移动字节

PacketInputStream not moving ahead bytes

我有一个这样的 PacketInputStream class:

public class PacketInputStream extends DataInputStream {

    private static final Charset UTF8 = Charset.forName("UTF-8");

    public PacketInputStream(InputStream myis) {
        super(myis);
    }

    public String readString() throws IOException {
        int length = readVarInt();
        byte[] data = new byte[length];
        readFully(data);
        return new String(data, UTF8);
    }

    public int readVarInt() throws IOException {
        int i = 0;
        int j = 0;
        while (true) {
            int k = read();
            if (k == -1)
                throw new IOException("End of stream");

            i |= (k & 0x7F) << j++ * 7;

            if (j > 5)
                throw new IOException("VarInt too big");

            if ((k & 0x80) != 128)
                break;
        }

        return i;
    }

    public long readVarLong() throws IOException {
        long varInt = 0;
        for (int i = 0; i < 10; i++) {
            byte b = readByte();
            varInt |= ((long) (b & (i != 9 ? 0x7F : 0x01))) << (i * 7);

            if (i == 9 && (((b & 0x80) == 0x80) || ((b & 0x7E) != 0)))
                throw new IOException("VarInt too big");
            if ((b & 0x80) != 0x80)
                break;
        }

        return varInt;
    }

    public byte[] readBytes() throws IOException {
        return readBytes(readShort());
    }

    public byte[] readBytes(int length) throws IOException {
        if (length < 0)
            throw new IOException("Invalid array length");
        byte[] data = new byte[length];
        readFully(data);
        return data;
    }

}

我有这个代码 运行:

System.out.println("Logic data version (always 0) : " + is.readVarInt());
        System.out.println("User ID: " + is.readVarLong());
        System.out.println("Home ID: " + is.readVarLong());

is定义

现在我遇到的问题是它总是显示 0 作为返回数字。

这是输入流的第一位: 00000000000000030035C708000000030035C708010000004 现在您可以看到,前 3 个不应该每次都给出 0 那么错误在哪里,我该如何解决?

谢谢:)

要么你输入的方式不符合代码,要么代码不符合输入的要求。以下是我如何执行代码:

main()

public static void main(String[] args) throws Exception {
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    byteArrayOutputStream.write(new byte[] { 0, 3,
            4, 5, (byte)128, 0, 0, 3, 0, 0, 3, 5, 0XC, 7, 0, (byte)8, 0, 0, 0, 0, 0, 0,
            0, 3, 0, 0, 3, 5, 0XC, 7, 0, 8, 0, 1, 0, 0, 0, 0, 0, 0, 4 });
    ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(
            byteArrayOutputStream.toByteArray());
    PacketInputStream is = new PacketInputStream(byteArrayInputStream);
    System.out
            .println("Logic data version (always 0) : " + is.readVarInt());
    System.out.println("User ID: " + is.readVarLong());
    System.out.println("Home ID: " + is.readVarLong());
}

更多要研究的项目:

  1. 为什么i |= (k & 0x7F) << j++ * 7;?为什么不 i |= (k & 0xFF) << j++ * 7;
  2. 为什么 int k = read();' and notbyte k = readByte();`? varinteger size > varlong size 是按字节读取的吗?
  3. 为什么 if ((k & 0x80) != 128) 而不是 if ((k & 0x80) == 128)?我相信if ((k & 0x80) != 128)是你期待终止读取整数的条件。
  4. if ((b & 0x80) != 0x80) 应该是 if ((b & 0x80) == 0x80) 吗?

下面是修改后的 class,我尝试读取 varint 后跟两个 varlong 作为我的输入:

    class PacketInputStream extends DataInputStream {

        private static final Charset UTF8 = Charset.forName("UTF-8");

        public PacketInputStream(InputStream myis) {
            super(myis);
        }

        public String readString() throws IOException {
            int length = readVarInt();
            byte[] data = new byte[length];
            readFully(data);
            return new String(data, UTF8);
        }

        public int readVarInt() throws IOException {
            int i = 0;
            int j = 0;
            while (true) {
                byte k = readByte();
                if (k == -1)
                    throw new IOException("End of stream");

                i |= (k & 0xFF) << j++ * 7;

                if (j > 5)
                    throw new IOException("VarInt too big");

                if ((k & 0x80) == 128)
                    break;
            }

            return i;
        }

        public long readVarLong() throws IOException {
            long varInt = 0;
            for (int i = 0; i < 10; i++) {
                byte b = readByte();
                varInt |= ((long) (b & (i != 9 ? 0x7F : 0x01))) << (i * 7);

                if (i == 9 && (((b & 0x80) == 0x80) || ((b & 0x7E) != 0)))
                    throw new IOException("VarInt too big");
                if ((b & 0x80) == 0x80)
                    break;
            }

            return varInt;
        }

        public byte[] readBytes() throws IOException {
            return readBytes(readShort());
        }

        public byte[] readBytes(int length) throws IOException {
            if (length < 0)
                throw new IOException("Invalid array length");
            byte[] data = new byte[length];
            readFully(data);
            return data;
        }

    }