使用Java编写的BitTorrent协议 - 成功握手后的位域。

6

成功地与多个节点建立握手后,BitTorrent消息链中的下一步是比特位图(bitfield)消息。

比特位图(bitfield)消息如下所示,其中顶部行说明协议段的字节大小:

<4-bytes><1-byte><x-bytes>
<nrOfBits><identifier><bits>

我遇到的问题是几乎所有的对等方发送的位图消息都与上述表示不同!这些消息通常看起来像这样:
size: 332, [0, 0, 0, 112, 5, 127, -1, -1, -1, -1, -5, -1, -1, -1, -1, -1, -17...]

第一个问题是我收到的大部分信息都有长度字节:

 [0, 0, 0, 112]

尽管在这种情况下接收到的消息总共包含332字节,而在其他情况下,消息可能只有80字节左右。
第二个问题是,位通常重复使用-1或某些奇怪的负值。
我认为这不能归因于我的低级编码问题,因为其他消息正常工作。
1个回答

5

问题1:

TCP是一种流协议,我认为你正在使用它。消息以不断的字节流形式传输。你需要自己将流分成单独的消息。从套接字中读取332个字节并不意味着你已经读取了一个完整的消息。比特流客户端通常会对消息进行流水线处理(同时发送多个消息,而不等待回答)。如果长度为[0,0,0,112],则消息的长度为4 + 1 + 111(4个字节的长度,一个字节的标识符和111个位域字节)。这就是全部内容。在这116个字节之后就是下一个消息。

编辑:尽管基于数据报导向的UDP,但uTP(uTorrent UDP传输协议)也存在同样的问题。

问题2:

你看到的是字节数组,在Java中它们始终是无符号的(这真的很烦人)。它们的范围始终在-128和127之间,因此当第一个(最高位)设置时,Java认为字节值为负数。因此,如果一个位域有一个字节的所有8个位都被设置(二进制11111111),你将得到一个字节值为-1,因为二进制11111111对应于二进制补码中的-1。我建议你以二进制形式或十六进制形式(使用类似于Integer.toHexString(myByte & 0xff)的东西)查看这些字节。

编辑:另外,除非你只是为了好玩而编写代码,否则我建议你使用现成的Java BitTorrent库。当已经存在已实现所需功能及更多的现有、经过良好测试的库时,从头开始编写此类内容几乎没有任何意义。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接