2009-11-09 67 views
2

从JavaDoc的用于setSoTimeoutjava.net.Socket.setSoTimeout是否可靠?

启用与 指定超时/禁用SO_TIMEOUT,以毫秒为单位。 如果将此选项设置为非零 超时,则与此 套接字关联的 InputStream上的read()调用将仅阻止该时间量 。如果超时到期,则提出一个 java.net.SocketTimeoutException异常,即 ,尽管Socket仍然是 有效。在进入阻止 操作之前必须启用该选项 才能生效。超时 必须> 0。超时为零时,将 解释为无限超时。

从各种互联网上的帖子我已阅读,SO_TIMEOUT采用Socket C API(例如here)时,是相当不可靠的。

因此,这个问题是否可靠使用setSoTimeout检查失控会话?

如果没有,您可以推荐什么技术来对套接字会话设置时间限制?

回答

3

我不知道任何相关的最近/当前操作系统,在哪个(流)套接字超时未按照它们应该工作。您链接的帖子来自一个相当混乱的海报,它试图在数据报套接字上设置发送超时,这是毫无意义的。数据报或者立即发送或者放弃丢弃。

+0

+1 - 链接的帖子确实非常困惑。除了UDP废话超时之外,他似乎认为你应该能够发送任意大的UDP数据报。 – 2009-11-10 00:05:21

0

查看Java 6 nio中的连接类,它们现在包括套接字,并执行非阻塞操作,因此如果您愿意,可以取消操作。

Apache的htmlclient核心(?)现在能够使用nio套接字,所以看起来他们有这个概念的工作。虽然这就是我所知道的。

+0

但是否nio套接字可以在网络堆栈损坏的OS上正常工作是任何人的猜测...... – 2009-11-10 00:15:38

+1

不仅可以取消nio操作,而且Selector.select(长超时)也可以工作。 – Seth 2009-11-10 03:48:18

+0

你能保证吗?在具有**破损**网络堆栈的计算机上?我会说你不能这样做,因为你不能认为实现select的系统调用对于套接字来说是正确的。 – 2009-11-10 04:21:28

2

我不知道任何现代平台的操作系统平台,其网络堆栈太破碎,套接字超时不起作用。但是如果有人知道真实生活的例子,请将其添加为评论!

我不担心这种情况,除非你真的被迫在这样一个破坏的操作系统上支持你的应用程序。我怀疑这将是一个痛苦的工作。

1

链接是关于SO_RCVTIMEO。问题是关于Socket.setSoTimeout()。在唯一的平台上,我知道前者无法工作的地方(某些版本的Solaris),后者使用select()方法搞定,这确实有效。该方法的合同要求它。除非有人真的想出了一个平台,而这个平台在16年前从未见过,否则你不必担心这一点。

+0

请注意,即使在Linux上,setSoTimeout也不会设置SO_RCVTIMEO选项。相反,超时值存储在内部,JRE使用轮询系统调用来实现读取超时。 – 2013-12-20 17:58:13