2009-06-22 39 views
1

我正在通过此spec使用Java实现BitTorent协议。在消息部分中,除2个外,所有消息都是固定长度的;对于其中的一个来说,它是握手后唯一的变量消息,所以我可以检查其他人,并在没有其他消息遇到时认为它是一条消息。但是,对于下面的消息解析可变长度消息

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

位域消息可以仅紧接在信号交换序列完成之后发送的,和任何其它消息发送之前。它是可选的,并且如果客户端没有分片,则不需要发送。

位字段消息是可变长度,其中X是位字段的长度。有效载荷是表示已成功下载的部分的位字段。第一个字节的高位对应片段索引0.清除的位表示缺失的片段,并且设置位指示有效且可用的片段。末尾的备用位设置为零。

错误长度的位域被视为错误。如果客户端接收到的字段大小不正确,或者位字段中有任何空闲位被设置,则客户端应该放弃连接。

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

编辑:在位字段消息的有效载荷中,每个作品在torrent文件中为0或1,消息的长度将根据torrent内容的大小而改变。所以我不认为我可以假设件数始终适合5个字节的数字。

+0

请标点符号! – JesperE 2009-06-22 21:42:06

+0

嘿,他在那里有一个分号! – skaffman 2009-06-22 21:46:06

+0

我把那个分号放在那里。 :P – 2009-06-22 21:47:53

回答

3

id字段将始终是消息的第5个字节,在len字段的四个字节之后。你可以做类似如下:

DataInputStream stream; 

// ... 

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

stream.readFully(payload); 

这应该对任何信息的工作,实际上,因为它们都具有相同的len + id头。

编辑:“所以我不认为我可以假设件数总是适合5个字节的数字。”

一个四字节长的字段可以处理有效载荷中最多2^32-1个字节,每个字节8位可以为您提供34,359,738,360个片段的空间。这应该是很多! :-)

1

我没有详细阅读规范,但没有明确知道可变长度字段的长度或一些终止分隔符,我看不出如何处理它。请问bitfield=<len=0001+X>不是或许表示您将告知(可变)长度的前期

2

我不能想出办法解析它 如果我不知道长度;

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

我该如何找到id在 字节流?

它看起来好像是每个消息中的第5个字节,紧跟在长度字段之后。因此,在完成解析前一个消息之后,您只需查看前5个字节即可。

2

在你引用的规范的早些时候,我读到:'长度前缀是一个四字节的big-endian值。'。我读到:读下四个字节,将它们转换为一个int,这应该是你的长度。如果您不熟悉字节到整型转换过程,我已经使用类似于this的东西。

+0

从我理解的阅读所有消息都是真实的规范,但位域和片段。由于我添加到问题的原因。 – 2009-06-22 22:08:14