我正在尝试学习 Socket,但是我对 Oracle 网站上的以下文本感到困惑:
setSoTimeout
public void setSoTimeout(int timeout) throws SocketException
以毫秒为单位启用/禁用具有指定超时时间的 SO_TIMEOUT。如果将此选项设置为非零超时时间,则与此 Socket 关联的 InputStream 上的 read() 调用仅会阻塞该时间量。如果超时时间到期,则引发 java.net.SocketTimeoutException,但 Socket 仍然有效。必须在进入阻塞操作之前启用该选项才能生效。超时时间必须 > 0。超时时间为零被解释为无限超时。
我的问题:
什么是
SO_TIMEOUT
?Socket 是连接的端点。如果我说
mySocket.setSoTimeout(2000);
这是否意味着我将在2000毫秒内阻止从服务器/客户端获取任何输入,而在此时间之后,套接字准备好读取数据?
什么是超时过期的意思?
在执行阻塞操作之前,必须启用哪个选项?
无限超时是否意味着套接字不再读取数据?
SO_TIMEOUT
是对操作系统特定机制的抽象。在Unix系统中,JVM使用poll或select。在Windows上,它使用仅适用于Windows的SO_RCVTIMEO
套接字选项。 - JoniSO_TIMEOUT
选项。如果你研究它的实现(至少在OpenJDK中),你会发现Windows实现使用SO_RCVTIMEO
,而Linux/Solaris实现则使用poll或select来达到相同的效果。请比较http://hg.openjdk.java.net/jdk7/jdk7-gate/jdk/file/9b8c96f96a0f/src/solaris/native/java/net/PlainSocketImpl.c和http://hg.openjdk.java.net/jdk7/jdk7-gate/jdk/file/9b8c96f96a0f/src/windows/native/java/net/TwoStacksPlainSocketImpl.c。 - JoniSocket
API 中没有 'SO_TIMEOUT
' 选项。有一个Socket.setSoTimeout()
方法,其 Javadoc 错误地提到了SO_TIMEOUT
,正如你在第一条评论中正确指出的那样,它不存在。我知道它是如何实现的,也知道原因。 - user207421poll
代替。如果你不明白为什么要讨论SO_TIMEOUT的实现方式,那么为什么要提出SO_RCVTIMEO呢? - Joni