java NIO SocketChannel 的读取超时?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17340970/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-01 01:43:32  来源:igfitidea点击:

Read timeout for an NIO SocketChannel?

javaniosocketchannel

提问by Sam

What is the best way to set a timeout to close a NIO SocketChannel if there is no data is received for a certain period after the connection is established?

如果在建立连接后的一段时间内没有接收到数据,那么设置超时以关闭 NIO SocketChannel 的最佳方法是什么?

回答by user207421

Either:

任何一个:

  1. You are using a Selector, in which case you have a select timeout which you can play with, and if it goes off (select(timeout)returns zero) you close all the registered channels, or

  2. You are using blocking mode, in which case you might think you should be able to call Socket.setSoTimeout()on the underlying socket (SocketChannel.socket()), and trap the SocketTimeoutExceptionthat is thrown when the timeout expires during read(), but you can't, because it isn't supported for sockets originating as channels, or

  3. You are using non-blocking mode without a Selector, in which case you need to change to case (1).

  1. 您正在使用 a Selector,在这种情况下,您有一个可以播放的选择超时,如果它关闭(select(timeout)返回零),您将关闭所有注册的频道,或者

  2. 您正在使用阻塞模式,在这种情况下,您可能认为您应该能够调用Socket.setSoTimeout()底层套接字 ( SocketChannel.socket()),并捕获在SocketTimeoutException期间超时到期时抛出的read(),但您不能,因为它不支持源自通道的套接字,或

  3. 您正在使用没有 的非阻塞模式Selector,在这种情况下,您需要更改为案例 (1)。

So you either need to use case (1) or a java.net.Socketdirectly.

所以你要么需要使用 case (1) 要么java.net.Socket直接使用。

回答by 111Yahro

I was looking for the same recommendation and could not find it easily - sharing it here.

我正在寻找相同的建议,但无法轻松找到 - 在这里分享。

There is a nice handler for netty called: ReadTimeoutHandler.

netty 有一个很好的处理程序,称为:ReadTimeoutHandler。

One can use it like that

一个人可以这样使用它

channel.pipeline().addLast(new ReadTimeoutHandler(readTimeout));

it will drop io.netty.handler.timeout.ReadTimeoutException when failed to see any data doing the defined read timeout.

当未能看到任何数据执行定义的读取超时时,它将删除 io.netty.handler.timeout.ReadTimeoutException。