InputStream 跳过字节

InputStream skip bytes

我正在使用 TCP 套接字与对等方通信,我看到当我读取第一条传入消息的 inputStream 时,一切顺利。然后,当我读取第二条传入消息的 inputStream 时,inputStream 跳过 第一个 n 字节(n 是不同的每个 运行).

中的正数

我怎么知道 inputStream 跳过 n 字节?使用 Wireshark,我可以看到第二条消息接收良好,但 Java TCP 套接字仍然忽略第一个 n 字节。

此外,Wireshark 本身向我展示了一些奇怪的东西 - 通过查看 Wireshark 中的第一条消息,它在末尾包含:第二条消息的开头。通过查看 Wireshark 中的第二条消息,消息的开头也出现在这里。

我不明白这是怎么回事。

技术细节 + Wireshark 照片:

  1. 我收到的第一条消息是 'Handshake' 消息。
  2. 我收到的第二条消息每次都不同,但大部分时间都是 'extended' 消息。
  3. 我检查了我的代码,但我只在两个地方读到相同的 InputStream:当我等待 'Handshake' 和当我等待其余消息时不等于 'Handshake' 消息。

我收到的第一条消息:

 * Offset       Size            Name        value
 * 0            8-bit           byte        pstrLength
 * 1            pstrlen-bit     bytes       pstr
 * 1+pstrlen    64-bit          byte        reserved
 * 9+pstrlen    20-bit          String      torrentInfoHash
 * 29+pstrlen   20-bit          String      peerId
 * 49+pstrlen
public HandShake(InputStream dataInputStream) throws IOException {
    byte[] data = new byte[1];
    dataInputStream.read(data);
    byte pstrLength = ByteBuffer.wrap(data).get();
    data = new byte[pstrLength + 48];// how much we need to read more.
    dataInputStream.read(data);

    ByteBuffer byteBuffer = ByteBuffer.allocate(1 + pstrLength + 48);
    byteBuffer.put(pstrLength);
    byteBuffer.put(data);
    HandShake handShake = HandShake.createObjectFromPacket(byteBuffer.array());

详细信息:13 直到 45 是第一条消息的内容 - Handshake00 直到 3a 是第二条消息的第一个 n 字节,它也将出现在这里:

我收到的第二条消息:

public static PeerMessage create(Peer from, Peer to, InputStream inputStream) throws IOException {
    byte[] data = new byte[4];
    boolean isPeerClosedConnection = (inputStream.read(data) == -1);
    if (isPeerClosedConnection)
        throw new IOException("the peer closed the socket:" + from.toString());
    int lengthOfTheRest = ByteBuffer.wrap(data).getInt(); // how much do we need to read more
    data = new byte[lengthOfTheRest];

    isPeerClosedConnection = (inputStream.read(data) == -1);
    if (isPeerClosedConnection)
        throw new IOException("the peer closed the socket:" + from.toString());

    ByteBuffer byteBuffer = ByteBuffer.allocate(4 + lengthOfTheRest);;
    byteBuffer.putInt(lengthOfTheRest);
    byteBuffer.put(data);

    return create(from, to, byteBuffer.array()); // initialize message object from byte[]
}

详细信息:00 直到 3a 是第二条消息的前 n 个字节。

当我读取 InputStream 时,我得到以下字节:从 6d65

为什么 Wireshark 显示相同的数据两次,为什么我的 InputStream 跳过第二条消息的前 n 个字节?

您写道:

I calculate how much to read and I use every byte.

你编码了:

data = new byte[pstrLength + 48];// how much we need to read more.
dataInputStream.read(data);

此代码与您的描述不符。第二个 read() 不能保证填满缓冲区。请参阅Javadoc。将其更改为 readFully().

注意 在您的 isPeerConnected 测试中还有另一个问题。您正在读取一个字节的输入并将其丢弃。如果它仍然连接,这将导致您失去与对等点的同步。