繁体   English   中英

InputStream 跳过字节

[英]InputStream skip bytes

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

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

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

我不明白发生了什么。

技术细节 + Wireshark 照片:

  1. 我收到的第一条消息是“握手”消息。
  2. 我收到的第二条消息每次都不同,但大多数时候它是“扩展”消息。
  3. 我检查了我的代码,我只在 2 个地方读取了相同的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());

在此处输入图片说明

详细信息: 1345是第一条消息的内容 - Handshake 00直到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个字节?

你写了:

我计算要读取的内容并使用每个字节。

你编码:

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM