使用Java的BitTorrent协议 - 成功握手后的Bitfield

时间:2014-12-22 11:48:55

标签: java network-programming nio network-protocols bittorrent

成功发送和接收来自多个对等方的握手后,BitTorrent消息链中的下一步是位域消息。

位域消息如下所示,其中顶行说明了协议段的字节大小:

<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 个答案:

答案 0 :(得分:5)

问题#1:

我认为你正在使用的TCP是一种蒸汽协议。消息以永无止境的字节流形式出现。您必须自己将流分成单独的消息。您在单次读取中从套接字读取332个字节的事实并不意味着您已读取单个消息。 Bit torrent客户端经常传递消息(一次发送多条消息,而不等待答案)。如果长度为[0,0,0,112],则消息的长度为4 + 1 + 111(长度为4个字节,标识符为1个字节,111个字节字节)。就是这样。在这116个字节之后出现下一条消息。

编辑:关于uTP,uTorrent基于UDP的传输协议也是如此,尽管它基于面向数据报的UDP。

问题#2:

你所看到的是一个字节数组,在java中总是没有符号(这真的很烦人)。它们的范围始终在-128到127之间,因此当设置第一个(最高有效位)时,java会将字节值视为负值。这样,如果位字段具有设置了所有8位的字节(二进制11111111),则由于二进制11111111对应于two's complement中的-1,因此您将获得-1的字节值。我建议以二进制形式或十六进制(使用类似Integer.toHexString(myByte & 0xff))的方式查看这些字节。

编辑:在另一个注释中,除非你为了它而编写代码,否则我建议using a ready-made Java BitTorrent library。当有现成的,经过良好测试的库来实现你需要的所有东西时,你自己从头开始编写这类东西的意义不大。