如何实现多个BitTorrent通告请求的超时?

时间:2019-07-07 22:56:30

标签: java multithreading bittorrent

我正试图使BitTorrent客户端仅用于学习目的。我将首先解释到现在为止我做了什么。

我创建了一个线程池,其大小是可用处理器的数量。现在,每个种子文件都在单独的线程上执行。我从每个torrent文件中获取跟踪器URL的列表,并使用java NIO发送连接请求。我假设我几乎同时发送所有连接请求,因为我只是循环访问URL列表并发送请求。因此,我无需维护每个URL的超时,而是在发送第一个请求时启动计时器。计时器超时后,我将连接请求重新发送到所有未响应的URL。 (在这里,我使用interval来计算计时器startTime并跟踪开始时间currentTimeMillis()。直到startTime+interval超过selector.select()为止,我一直循环。选择准备就绪的channels。当循环退出时,我将连接请求重新发送到所有未响应的通道。我没有使用TimerScheduledExecutorService,因为我认为这可能会导致爆炸的线程数。我已经在每个文件中使用一个线程。对此进行更正,并提出更好的方法。)

主要问题是在发送公告请求时出现的。我可能会在任何时间收到连接响应,这时我应该发送宣告请求并启动计时器,如果请求超时则重新发送该请求。当前,对于每个连接响应,我向线程池提交一个Runnable任务,该任务处理宣告请求的发送。所以我在每个宣布请求-响应周期中使用一个线程。因此,如果我有许多种子文件,并且每个文件至少有5个跟踪器URL,这不会造成性能问题吗?有什么更好的方法可以使此功能正常运行?如果有人可以对torrent客户端如何同时处理这么多文件和这么多请求响应周期有所了解,那将是非常有启发性的。

1 个答案:

答案 0 :(得分:0)

使用nio或基于选择器的库(如netty)的主要好处是允许您将多个网络连接复用到单个对象中,而仅在该对象上等待。复用定义为comprising several interleaved parts。在这种情况下,您将以前需要单个线程等待的多个网络连接编织到单个概念对象(Selector)中,该对象仅需要单个线程等待。在您的情况下,您可以将整个网络连接编织到一个选择器中,然后在单个线程中等待。这样,就不会增加线程。以这种方式重新架构系统可能需要为每个连接做更多的簿记工作,而这些工作以前在负责处理该连接的线程中是本地的。

此外,请勿使用System#currentTimeMillis来计算时差,而应使用System#nanoTime,因为它将不受系统时间的任何更改的影响。