Java中的Bittorrent实现&&需要一些关于群体行为的信息

2022-09-02 14:11:04

我正在用Java开发一个bitTorrent客户端。我知道网上有很多图书馆,但我忍不住。我想要我自己的。无论如何,我注意到一些奇怪的行为,也许你们知道我错过了一些东西:

  • 在我尝试连接的所有对等体中,大约有 80% 会导致连接不成功(或者“无法连接”错误)。显然,对等节点列表是从跟踪器接收的。我还通过尝试ping来随机测试一些IP;ping 通常成功。socketTimeOut
  • 当我连接时:
    • 50%掉线后手摇,
    • 在30%上,我注意到一个奇怪的行为:我收到握手,我收到BitField(他们都有碎片),我被+20有消息轰炸(我检查了他们在BitField中已经提到的碎片索引),然后他们断开连接,这很奇怪。

(对于所有统计数据,数字并不精确。

一些BitTorrent问题:

更新#4:由于考虑找到答案,我切断了一些问题

  • 这是“80%的连接失败率问题”: 我的80%连接率失败的原因是什么?这不可能是运气不好,因为我试图联系的每个客户都没有更多的空间给我。我正在收听6881,但也用其他端口进行了测试。昨天我取得了巨大的成功,一堆连接被接受(相同的代码,过去一周的一些变化),Piece消息开始流动。所以我的代码不是完全无用的。

  • 在关闭之前,torrent客户端是否会向跟踪器发送最后一条消息,以使其使用对等信息更新其内部数据库,以便它不会作为响应发送具有无用对等信息的列表?或者只是他们应该..因为看起来我真的在接收死去的同龄人。event=stopped

  • 接收的同行的顺序是否重要?也许是完成百分比..或者真的是随机的。
  • 此外,我时不时地会收到一个端口为0的对等体,这使我的套接字构造函数引发异常。端口 0 是什么意思?我可以在任何端口联系它吗?
  • 我的 PeerId(我在握手时发送的 Id 或向智能设备宣布我自己)是否会影响我尝试通信的洪流客户端是否将继续开始连接?这意味着如果我撒谎并说我是 Azureus 客户端,并使用“-AZ2060-”作为我的 ID,该怎么办?
  • 这就是“碎片可用性吓跑同行的问题”: 我的碎片可用性会吓跑同行吗?我正在尝试连接,并且我发送了一个空的位字段(我没有碎片,[长度:1][Id = 5][有效载荷:{}]);似乎他们发送比特菲尔德,我发送比特菲尔德。(有些人疯狂地发送消息),他们意识到我很穷,他们放弃了我。有些在握手后断开连接。(多么粗鲁。
  • 不使用经典端口间隔:6881 - 6889 是否有好处?
  • 这是“不良对等体列表问题”: torrent客户端是否在内部保留不良对等体列表(如黑名单)?有时在找到一个不错的同行后,我在测试中不断使用它的信息,但只接受了1/3的连接。有时必须经过 10 分钟才能再次成功连接。

更新#1:似乎与μTorrent客户端的连接以上述模式(BITFIELD,HAVE BOMBATING,Close Connection)运行。我用一堆bitTorrent客户端(μTorrent,BitTorrent,Vuze,BitCommet,Deluge)进行了本地测试,只在μTorrent上注意到了这个模式。在其他方面,沟通很好(HS,BITFIELD,UNCHOCE和happy piece sharing)。现在,这个μTorrent可能是最流行的bitTorrent客户端(6/8连接启动是μTorrent),所以...任何想法?

更新#2:就保持而言,它看起来确实如此(这样做实际上是有道理的)。例如,使用μTorrent,我注意到以下无连接间隔(30秒,1分钟,1分钟30秒,2分钟)。“no-connect”的意思是,在上一个连接结束后,几秒钟内没有接受任何新连接。"bad list,"x

更新#3:HAVE消息轰炸可能是所谓的“懒惰的bitfield”(做了几个测试,HAVE中提到的每个部分都不存在于BITFIELD中)。我看到μTorrent和BitTorrent使用这种方法。

另一个结论是:一些客户端在尊重BitTorrent规范方面更具限制性,如果您违反规则,它们将关闭连接。前任:我注意到BitTorrent和BitTornado,如果你发送一个bitfield消息但没有碎片,它们将关闭连接(没有碎片=空的bitfield....但规范说“它是可选的,如果客户端没有碎片,则不需要发送”),而其他人关闭连接,如果你在发送UNCHOKE消息之前发送任何类型的消息(甚至不感兴趣)。

更新#4:由于我最感兴趣的是第一个问题(我的80%未能连接率的原因是什么?..被删除的问题可能比喜欢的更多),这里有一些解释为什么有时连接不成功:

1)如果我在停止上一个连接后不久开始与对等体的连接(通过停止 - 我的意思是关闭套接字):另一端的对等体在下一次读/写之前不会知道。

细节: - 我注意到这一点很多次,这在完成下载后更加明显。如果我关闭连接,对等体不会意识到这一点,直到它尝试发送新的KEEP_ALIVE(约2分钟)。但是,如果我在交换请求片段时关闭,同行将很快意识到。在关闭连接后的第一种情况下,我仍然存在于uTorrent对等选项卡中。如果我在记录器选项卡内查看,大约2分钟后,它会意识到我走了。

2)似乎uTorrent看到我的BITFIELD消息损坏了(显然应该在收到它后关闭连接)(这并不总是发生......我也检查并重新检查,msg是好的,与其他BT客户端没有这样的问题)。

详细信息: - 如果我查看uTorrent记录器选项卡内部,它会在我发送bitfield后立即显示“断开连接:坏数据包” - 我打算尝试实现lazzy bitfield,也许我可以逃脱这个(我也看到大多数BT客户端这样做)

3)(很可能链接到#1)当uTorrent不允许我重新连接时,我在记录器选项卡中看到:“断开连接:已经具有相等的连接(丢弃了额外的连接)”。目前,我在启动新连接时选择随机本地端口(在大多数BT客户端中都看到了这一点),但这并没有欺骗它,他仍然看到im是一个已经存在于他的“对等列表”中的对等体(可能确实ip匹配)。Buuut:在30%的测试中,同样的情况,它确实允许我重新连接:).我还没有解释为什么

4)还有一件事:在你关闭uTorrent中的洪流后,似乎“传入连接的侦听器”仍然活着(通过关闭我的意思是:右键单击+停止)。这意味着我仍然可以启动连接,发送握手。在此之后,我断开连接(它不会握手回来)。uTorrent记录器中的消息:“断开连接:没有这样的洪流:80FF40A75A3B907C0869B798781D97938CE146AE”,这个长字符串是我的信息哈希。在与其他BT客户端进行测试时也看到了这一点。

更多信息

  • uTorrent类型的完全上传/部分上传和完全下载的场景是成功的,部分下载的场景不是那么多。可能是由于#2
  • 我仍然得到uTorrent那个bitField +有轰炸+紧密的联系。因为我记得记录器选项卡中的相同消息“断开连接:坏数据包”。可能是由于#2
  • 除了uTorrent之外,我还测试过:BitTorrent,BitTornado,BitCommet,qBitTorrent,FlashGet(通信还可以)和Vuze,FrostWire,Shareaza(与这些家伙一起,它超级OK)。
  • 并非所有客户端的行为都相同。例如:FlashGet & uTorrent (& BitCommet?) 在你发送 INTERESTED 之前不要取消选择。而其他人似乎在比特菲尔德之后立即松开了。从这个意义上说,我计划以某种方式以不同的方式对待客户(我真的认为这是必要的)。可能从比特场猜出他们的名字(只有2个命名约定)并从那里开始。我已经实现了一些东西,这就是我如何知道我连接到uTorrent类型的客户端。

答案 1

好吧,我有一个答案给你,但我必须警告你,我自己从来没有写过一个bit-torrent客户端,有些答案可能不是100%准确的,我写的一切都是基于我对bit-torrent如何工作的全球观点的理解。因此,如果我浪费了你的时间,我很抱歉,但我仍然认为你可能会从我的答案中了解你所问的核心问题。

•我的80%连接率失败的原因是什么?

用一个线性解释来解释非常复杂,但是: - 有点洪流意识形态是针锋相对的。如果你不给予/有针锋相对,你就不会得到针锋相对。除非您刚刚开始下载,在这种情况下,您可能会从中获得“捐赠”开始...或者另一边是专用的播种机。在这种情况下,他可能会检查你是一个给予者还是只是一个接受者......或者许多当前正在下载此内容...或(填写您的想法..)所以,你会看到有很多,实际上非常聪明的机制,以确保蜂群可以敏捷和高效,虽然其中一些可以追溯到你的机器,但其中大多数甚至不能真正被你的机器监控,更不用说在它的控制下。

•torrent 客户端是否在关闭之前向跟踪器发送具有 event=stop 的最后一条消息,以使其使用对等信息更新其内部数据库,以便它不会作为响应发送包含无用对等信息的列表?或者只是他们应该..因为看起来我真的在接收死去的同龄人。

  • 这取决于客户端代码 - 有些人可能会这样做,有些人不会这样做。(继续阅读)

•接收对等体的顺序是否重要?也许是完成百分比..或者真的是随机的。

  • 这取决于服务器代码 - 有些人可能会这样做,有些人不会这样做。(继续阅读)

好吧,注意这两个(继续阅读)笔记。您应该记住,在P2P网络中,即使协议规定了应该做的事情,也无权严格约束客户端甚至服务器来维护协议 - 这并不意味着每个客户端都会实现它或对它采取相同的行动或错过它。

•此外,我时不时地会收到端口为 0 的对等体,这使我的 Socket 构造函数引发异常。端口 0 是什么意思?我可以在任何端口联系它吗?

  • 端口 0 有点像通配符,如果您连接到它 - 它会自动将您连接到下一个可用端口。(有人说下一个可用的端口高于1023 - 但我从未测试过)

•我的 PeerId(我在握手时发送的 Id 或向智能设备宣布自己)是否会影响我尝试通信的 torrent 客户端是否将继续开始连接?这意味着如果我撒谎并说我是 Azureus 客户端,并使用“-AZ2060-”作为我的 ID,该怎么办?

它会认为你是Azureus,如果其他Azureuses根据这一点促进与Azureuses的连接(如果有的话,这是一个很大的问题),你将从中受益。

•我的件件可用性是否会吓跑同行?我正在尝试连接,并且我发送了一个空的位字段(我没有碎片,[长度:1][Id = 5][有效载荷:{}]);似乎他们发送比特菲尔德,我发送比特菲尔德。(有些人疯狂地发送消息),他们意识到我很穷,他们放弃了我。有些在握手后断开连接。(多么粗鲁。

  • 可能。。

•不使用经典端口间隔:6881 - 6889 是否有好处?

  • 我不这么认为 - 除了可能混淆你的ISP。

• 洪流客户端是否在内部保留不良对等节点列表(如黑名单)?有时在找到一个不错的同行后,我在测试中不断使用它的信息,但只接受了1/3的连接。有时必须经过 10 分钟才能再次成功连接。

  • 取决于客户端代码。

总结

这是一个丛林 - 只要他发送正确的协议命令,每个人都可以编写自己的逻辑 - 你的问题集中在客户端的逻辑行为上,但正如你现在可能已经理解的那样,没有共同点,这也是bit-torrent的美妙之处,可能是它成功的主要原因。


答案 2

推荐