我正尝试用Java编写BitTorrent客户端,以供练习。对于跟踪器连接,我正在使用torrent文件的announce-list
字段中的URL。为了与跟踪器进行实际通信,我使用了java nio(DatagramChannel和选择器)而不是线程,并且它可以正常工作。但是,根据洪流规范,如果未收到相应的响应,则每15 * 2^n
秒重新发送一次请求。当我通过NIO
搜索解决方案时,找不到任何解决方案。但是,我发现了很多对Timer
和TimerTask
类的引用。所以我的问题是:应该使用NIO
还是使用TimerTask
来安排跟踪程序请求的发送?如果答案是NIO
,如何使用NIO
实现重传?
答案 0 :(得分:0)
也许使用ScheduledExecutorService
来触发延迟的任务并使用NIO执行操作?与TimerTask
相比,它具有一些优势。您可以继续使用NIO,以避免阻塞应用程序的网络I / O部分。
答案 1 :(得分:0)
阻塞(每个连接的线程)与非阻塞(选择器+非阻塞模式下的通道)和任务调度是正交的。
IO的阻止模式与线程建立后与套接字的交互方式有关,涉及吞吐量,延迟,并行性以及代码复杂性。阻塞IO相对简单,可以轻松提供高吞吐量。非阻塞IO(至少java.nio
,不支持简化的IO)可能相当复杂,但可以并行处理更多连接,而不会增加进程的线程数。
任务调度用于在IO发生之前设计应用程序逻辑,例如决定在打开下一个连接之前将任务推迟一个小时,而不必将整个线程专用于一个小时。
由于您可能只会在阻塞IO的时间处理少量HTTP连接,即,像HttpURLConnection
这样的简单HTTP客户端可能就足够了。但是,如果您使用的是Java 11或更高版本,则最好使用java.net.http.HttpClient
API,该API确实在后台使用了NIO,同时为您处理了大多数复杂性。
无论哪种情况,都可以通过Timer
或ScheduledExecutorService
来推迟下一个公告。