如何在阻塞模式NIO中实现超时?

时间:2013-02-27 19:13:11

标签: java sockets networking io nio

我没有使用任何选择器或类似的东西。我只有一个简单的ServerSocketChannel监听和SocketChannel以阻塞模式连接到它。我想在连接上施加超时,但SocketChannel.socket().setSoTimeout()不起作用。

我尝试让后台线程休眠30秒并检查变量是否仍然是null(因为它会阻止等待读入该变量)但是我无法正确地同步变量不能访问我的匿名类中的局部变量。

还有其他方法可以实现这一目标吗?

更新:我说错了我的问题。我还想在读取操作和连接本身上超时。

2 个答案:

答案 0 :(得分:2)

setSoTimeout()设置读取超时,而不是连接超时,并且由于某种原因,它在SocketChannels上根本不起作用,即使在阻塞模式下,甚至包装流也是如此。

您正在寻找的方法是channel.socket().connect(),有两个参数。

答案 1 :(得分:-1)

据我所知,在nio中使用同步操作是不可能的。通过Socket.setSoTimeout()设置的套接字超时会影响读取和写入,但不会建立连接。

即使在系统库级别,连接超时也不同于读/写超时 - 有关详细信息,请参阅man 2 connectman 2 setsockoptman 7 socket。因此,如果您在连接时需要真正的应用程序控制超时,则需要使用异步连接协议和相应的Selector,检查SelectionKey.isConnectable()等。不幸的是,这使得代码相当长一些。

我现在没有Java lib源码,但是看看内部如何实现Socket.connect(SocketAddress endpoint,int timeout)会很有趣 - 但我相信它也在内部使用select()