NIO SocketChannel 的读取超时?

5

在建立连接后,如果一定时间内未收到任何数据,如何设置超时以关闭NIO SocketChannel?

2个回答

13

要么:

  1. 您正在使用一个选择器(Selector),在这种情况下,您有一个可供调整的选择超时时间,如果超时了(select(timeout)返回0),您需要关闭所有已注册的通道。

  2. 您正在使用阻塞模式,在这种情况下,您可能认为可以在底层套接字(SocketChannel.socket())上调用Socket.setSoTimeout() 并捕获在read()期间超时过期时抛出的SocketTimeoutException,但事实并非如此,因为对于作为通道生成的套接字,它不受支持。

  3. 您正在使用无阻塞模式而没有选择器,在这种情况下,您需要转换到情况(1)。

因此,您需要使用情况(1)或直接使用java.net.Socket


我正在使用第一种情况。但是,据我所知,如果没有选择任何通道,则会触发 select(timeout)。我所需要做的是,在给定时间内,如果已连接的 SocketChannel 没有发送任何可读数据(即从 OP_ACCEPT 更改为 OP_READ)则关闭它。我的意思清楚吗? - Sam
1
当然了,但是在第一种情况下你不能直接这样做。你需要跟踪每个频道上次读取的时间并操纵选择超时,以便最近未读取的频道超时,如果没有任何操作,检查所有频道是否超时等等。 - user207421
对不起,您说的“操作选择超时”是什么意思? - Sam
2
根据此前的问题,情况#2将不起作用。但是它有一个显示如何解决的答案。 - Matthieu
@Sam,改变它的值? - user207421

1
我在寻找同样的建议,但很难找到 - 在这里分享一下。
有一个称为ReadTimeoutHandler的netty处理程序非常好用。
可以像这样使用它:
channel.pipeline().addLast(new ReadTimeoutHandler(readTimeout));

当在规定的读取超时时间内未看到任何数据时,它将会抛出 io.netty.handler.timeout.ReadTimeoutException。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接