如何在阻塞模式NIO中实现超时?
我没有使用任何选择器或类似的东西。 我只是一个简单的ServerSocketChannel
监听和一个SocketChannel
在阻塞模式下连接到它。 我想在连接上施加超时,但SocketChannel.socket().setSoTimeout()
不起作用。
我尝试让后台线程hibernate30秒并检查变量是否仍为null
(因为它将阻止等待读入该变量)但我无法正确同步变量,因为我无法访问我的局部变量匿名课。
还有其他方法可以实现这一目标吗?
更新:我说错了我的问题。 我还希望读取操作以及连接本身超时。
setSoTimeout()
设置读取超时,而不是连接超时,并且由于某种原因,它在SocketChannels
上根本不起作用,即使在阻塞模式下,甚至包装流也是如此。
您正在寻找的方法是channel.socket().connect()
有两个参数。
据我所知,在nio
使用同步操作是不可能的。 通过Socket.setSoTimeout()
设置的套接字超时会影响读取和写入但不会建立连接。
即使在系统库级别,连接超时也不同于读/写超时 – 请参阅man 2 connect
, man 2 setsockopt
和man 7 socket
以获取血腥细节。 因此,如果您在连接时需要真正的应用程序控制超时,则需要使用异步连接协议和相应的Selector
,检查SelectionKey.isConnectable()
等。 不幸的是,这使得代码相当长一些。
我现在没有Java lib源代码,但是看看Socket.connect(SocketAddress endpoint,int timeout)
是如何在内部实现的将会很有趣 – 但我相信它也在内部使用select()
。