【问题标题】:How to implement timeouts for multiple BitTorrent announce requests?如何为多个 BitTorrent 公告请求实现超时?
【发布时间】:2019-07-07 22:56:30
【问题描述】:

我正在尝试制作一个 BitTorrent 客户端,仅用于学习目的。我将首先解释我到目前为止所做的事情。

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

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

【问题讨论】:

    标签: java multithreading bittorrent


    【解决方案1】:

    使用 nio 或基于选择器的库(如 netty)的主要好处是允许您将多个网络连接多路复用到单个对象中,并且只等待该对象。 Multiplex 的定义是comprising several interleaved parts。在这种情况下,您将多个网络连接(以前需要单独的线程等待)编织到一个概念对象(Selector)中,该对象只需要一个线程等待。在您的情况下,您可以将整个网络连接编织到一个单一的选择器中,并在一个线程中等待它。这样就不会有线程的扩散。以这种方式重新架构您的系统可能需要为每个连接进行更多的簿记,这些连接以前对于负责处理该连接的线程来说是本地的。

    另外,不要使用 System#currentTimeMillis 来计算时差,而是使用 System#nanoTime,因为它不会受到系统时间的任何更改的影响。

    【讨论】:

    • 如何处理 nio 中每个连接的超时?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-11
    • 2011-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-09
    相关资源
    最近更新 更多