我正在用 Java 开发一个 bitTorrent 客户端。我知道网上有很多图书馆,但我无能为力;我想要我自己的。无论如何,我注意到一些奇怪的行为,也许你们知道我缺少的东西:
- 我尝试连接的所有对等方中约有 80% 导致连接不成功(
socketTimeOut
或者“无法连接”错误)。显然,对等点列表是从跟踪器接收到的。我还通过尝试 ping 随机测试了一些 IP;ping 通常是成功的。 - 当我连接时:
- 握手后 50% 断开连接,
- 在 30% 时,我注意到一个奇怪的行为:我收到握手,我收到 BitField(他们有所有片段),我被 +20 有消息轰炸(我检查了他们已经在 BitField 中提到的片段索引),然后他们断开连接,这很奇怪。
(对于所有统计数据,数字并不准确。)
一些 BitTorrent 问题:
更新#4:由于考虑找到答案,我切断了一些问题
这是“80% 失败的连接率问题”:
我 80% 的连接失败率可能是什么原因?这不可能是坏运气,因为我尝试连接的每个客户都没有更多空间给我了。我正在听 6881,但也用其他端口进行了测试。昨天我取得了巨大的成功,接受了一堆连接(相同的代码,过去一周进行了一些更改),消息开始流动......所以我的代码并不是完全没用。Torrent 客户端是否在关闭之前向跟踪器发送最后一条消息,
event=stopped
以使其使用对等信息更新其内部数据库,以便它不会作为响应发送包含无用对等信息的列表?或者只是他们应该......因为看起来我真的收到了死去的同龄人。- 接收到的对等点的顺序是否重要?也许完成百分比..或者真的是随机的。
- 此外,我时不时地收到一个端口为 0 的对等点,这使我的 Socket 构造函数抛出异常。端口 0 是什么意思?我可以在任何端口上联系它吗?
- 如果我尝试通信的 torrent 客户端将继续启动连接,我的 PeerId(我发送握手或向跟踪器宣布我自己)会影响吗?这意味着如果我通过使用“-AZ2060-”作为我的 ID 撒谎并说我是 Azureus 客户怎么办?
- 这是“吓跑同行的问题”:
我的作品可用性会吓跑同行吗?我正在尝试连接,我发送了一个空位域(我没有碎片,[length: 1][Id = 5][payload: {}]
);似乎他们发送位域,我发送位域..(有些发疯了有消息),他们意识到我很穷,他们放弃了我..握手后断开连接。(真没礼貌。) - 不使用经典端口间隔:6881 - 6889 有什么好处吗?
- 这是“不良同行问题列表”:
洪流客户端是否在内部保留了不良对等点的列表(如黑名单)?有时在找到一个不错的对等点后,我会在测试中不断使用它的信息,但只接受了 1/3 的连接。有时必须经过 10 分钟才能再次成功连接。
更新 #1:似乎与 μTorrent 客户端的连接以上述模式运行(BITFIELD、HAVE 轰炸、关闭连接)。我用一堆 bitTorrent 客户端(μTorrent、BitTorrent、Vuze、BitComet、Deluge)在本地进行了测试,只在 μTorrent 上注意到了这种模式。在其他方面,沟通很好(HS、BITFIELD、UNCHOCE 和快乐的作品分享)。现在,这个 μTorrent 可能是最流行的 bitTorrent 客户端(启动的 6/8 连接是 μTorrent),所以……有什么想法吗?
更新#2:就保持 a 而言,"bad list,"
它看起来确实如此(而且这样做实际上很有意义)。例如,使用 μTorrent,我注意到以下无连接间隔(30 秒、1 分钟、1 分钟 30 秒、2 分钟......)。“无连接”的意思是,在先前的连接结束后,x
几秒钟内没有接受新的连接。
更新#3: HAVE 消息轰炸可能是所谓的“惰性位域”(进行了几次测试,HAVE 中提到的每个部分都没有出现在 BITFIELD 中)。我看到 μTorrent 和 BitTorrent 使用这种方法。
另一个结论:一些客户端在尊重 BitTorrent 规范方面更具限制性,如果您违反规则将关闭连接。例如:我在使用 BitTorrent 和 BitTornado 时注意到,如果您发送位域消息但没有片段,它们将关闭连接(没有片段 = 空位域.. 但规范说“这是可选的,如果客户端没有片段则不需要发送"),而其他人在发送 UNCHOKE 消息(甚至不感兴趣)之前发送任何类型的消息时会关闭连接。
更新#4: 由于我对第一个问题最感兴趣(我 80% 的连接失败率可能是什么原因?.. 被击中的问题可能更受欢迎),这里有一些解释为什么有时连接不成功:
1)如果我在停止前一个连接后不久开始与对等方的连接(通过停止 - 我的意思是关闭套接字):另一端的对等方直到下一次读/写才会知道。
详细信息: - 我多次注意到这一点,完成下载后更明显.. 如果我关闭连接对等方直到它尝试发送新的 KEEP_ALIVE(约 2 分钟)才会意识到这一点。但是如果我在交换 REQUEST-PIECE 时关闭,对等点会很快意识到。在关闭连接后的第一个场景中,我仍然存在于 uTorrent 对等点选项卡中。如果我查看记录器选项卡,大约 2 分钟后,它会意识到我已经走了。
2)似乎uTorrent看到我的BITFIELD消息已损坏(并且显然应该在收到它后关闭连接)(这并不总是发生......我也检查并重新检查了,味精没问题并且与其他BT客户端没有这样的问题) .
详细信息: - 如果我查看 uTorrent 记录器选项卡,它会在我发送位域后立即显示“断开连接:错误数据包” - 我正计划尝试实现惰性位域,也许我可以逃避这个(我也看到大多数 BT客户这样做)
3)(很可能链接到#1)当uTorrent不允许我重新连接时,我在记录器选项卡中看到:“断开连接:已经有相等的连接(删除了额外的连接)”。目前我选择随机本地端口启动新连接时(在大多数 BT 客户端中都实现了这一点),但这并没有欺骗它,他仍然看到我的“对等列表”中已经存在一个对等点(可能 ip 匹配).. Buuut:在 30% 的测试中,在相同的情况下,它确实允许我重新连接:) .. 我还没有解释为什么
4)还有一件事:在您关闭 uTorrent 中的种子后,“传入连接的侦听器”似乎仍然存在(关闭我的意思是:右键单击 + 停止)。这意味着我仍然可以开始连接,发送 HANDSHAKE.. 在此之后,我断开连接(它不会返回 HANDSHAKE)。uTorrent 记录器中的消息:“断开连接:没有这样的 torrent:80FF40A75A3B907C0869B798781D97938CE146AE”,这个长字符串是我的信息哈希.. 在与其他 BT 客户端进行测试时也看到了这一点。
更多信息:
- uTorrent 类型为 full-upload/partial-upload & full-download 的场景是成功的,partial-download 没有那么多.. 可能是由于#2
- 我仍然使用 uTorrent 得到 bitField + 有轰炸 + 关闭连接.. 因为我记得在记录器选项卡“断开连接:坏数据包”中相同的消息 .. 可能是由于 #2
- 除了 uTorrent,我还测试过:BitTorrent、BitTornado、BitComet、qBitTorrent、FlashGet(通信正常)和 Vuze、FrostWire、Shareaza(这些人非常好)。
- 并非所有客户端的行为都相同。例如:FlashGet 和 uTorrent(和 BitComet?)在您发送 INTERESTED 之前不要取消 .. 而其他人似乎在 BITFIELD 之后立即取消 .. 从这个意义上说,我计划以不同的方式对待客户(我真的认为这是必要的) .. 可能从位域猜测他们的名字(只有 2 个命名约定)并从那里开始.. 我已经实现了一些东西,这就是我知道我连接到 uTorrent 类型的客户端的方式..