我正在通过此规范使用Java实现BitTorent协议。在消息部分,所有消息都是固定长度,除了其中2个;对于其中一个,它是握手后唯一的可变消息,所以我可以检查其他消息,并假设当没有其他消息满足时它是一条消息。但是对于以下消息

bitfield: <len=0001+X><id=5><bitfield>
     

位域消息只能在握手序列完成后立即发送,并且在发送任何其他消息之前发送。它是可选的,如果客户端没有碎片,则无需发送。

     

位域消息是可变长度,其中X是位域的长度。有效负载是表示已成功下载的部分的位域。第一个字节中的高位对应于片段索引0.清除的位表示丢失的片段,而设置的位表示有效且可用的片段。最后的备用位设置为零。

     

错误长度的位域被视为错误。如果客户端接收到不正确大小的位域,或者如果位域设置了任何备用位,则客户端应断开连接。

如果我不知道长度,我无法想出解析它的方法;我怎么能在一个字节流中找到id?

编辑:在位域消息的有效负载中,对于torrent文件中的每个片段,消息的长度为0或1,消息的长度将根据种子内容的大小而变化。所以我认为我不能假设片段的数量总是适合5个字节的数字。

有帮助吗?

解决方案

id字段将始终是消息的第5个字节,位于len字段的四个字节之后。您可以执行以下操作:

DataInputStream stream;

// ...

int    length  = stream.readInt();
byte   id      = stream.readByte();
byte[] payload = new byte[length - 1];

stream.readFully(payload);

实际上,这应该适用于任何消息,因为它们都具有相同的<=> + <=>标题。

编辑: <!>“所以我认为我不能假设作品的数量始终符合5个字节的数字。<!>

四字节长度字段可以处理有效负载中最多2 ^ 32-1个字节,每字节8位,可以为34,359,738,360个字节提供空间。那应该够多了! : - )

其他提示

  

我无法想出解析它的方法   如果我不知道长度;

根据描述判断,长度在消息的前4个字节中给出。

  

我应该如何找到一个id   字节流?

看起来id是每个消息中的第5个字节,就在长度字段之后。因此,在完成解析上一条消息后,您只需要查看前5个字节。

在您引用的规范的前面,我读到:'长度前缀是一个四字节的大端值。'。我把它读作:读取接下来的四个字节,将它们转换为int,这应该是你的长度。如果您不熟悉字节到内部转换过程,我使用了类似于的内容。这

我没有详细阅读规范,但没有明确知道可变长度字段的长度或某些终止分隔符,我也看不到你如何处理它。 bitfield=<len=0001+X>不是是否表示您告知(可变)长度预先

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