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

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

我尝试让后台线程hibernate30秒并检查变量是否仍为null (因为它将阻止等待读入该变量)但我无法正确同步变量,因为我无法访问我的局部变量匿名课。

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

更新:我说错了我的问题。 我还希望读取操作以及连接本身超时。

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

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

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

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

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