0

我一直在研究 java.nio 的异步功能,到目前为止我是这个AsynchronousByteChannel类的粉丝,因为它让我可以为每个读取或写入操作提供完成回调。这很适合 scala 的Future类。

现在我正在尝试与DatagramChannel异步交互。(出于好奇,我正在尝试实现自己的 torrent 客户端,并且一些跟踪器使用 UDP。)

我现在的目标是找到一种方法来适应其原始签名的当前read和方法...write

def write(src: ByteBuffer): Int
def read(dest: ByteBuffer): Int

到一个面向 scala-futures 的签名,比如......

def write(src: ByteBuffer): scala.concurrent.Future[Int]
def read(dest: ByteBuffer): scala.concurrent.Future[Int]

查看 API 并在线查找示例,并找到了进入Selector类的方法。据我所知,这就是我需要用来制作DatagramChannel“非阻塞”的方法,但我看到了三种似乎相关的方法:

select() - blocks until a selection is ready
select(timeout) - blocks until either a selection is ready or timeout is reached
selectNow - doesn't block, but is useless if called before a selection is ready

因此,看来我对“非阻塞”的选择是阻塞(wtf?)或占用一个运行繁忙循环的线程,该循环重复调用其中一个选择方法。这是我的问题。

有没有办法使用 a 实现真正的非阻塞 IO DatagramChannel?如果不是,处理(阅读“最小化”)实际阻塞的最佳方法是什么?

4

1 回答 1

0

利用专用的选择器线程根本不是问题。首先,这是不可避免的。其次,AsynchronousByteChannel 实现也在后台使用后台线程。

至于使用 Selector 的最佳方式,我相信我在SelectorThread实现中找到了一个(注意它仍然在“工作”分支中)。我没有尝试使用 DatagramChannel,但它应该可以工作:只需以与 AsyncSocketChannel1 相同的方式实现AsyncDatagramChannel

于 2013-07-09T12:13:29.750 回答