java-setSoTimeout的功能是什么以及如何工作?
我正在尝试自己学习Socket。 我对Oracle网站上的文字感到困惑。 我对此有一些疑问。 在此先感谢您的明确解释。
setSoTimeout
公共无效setSoTimeout(int超时)引发SocketException
以指定的超时时间启用/禁用SO_TIMEOUT,以毫秒为单位。 将此选项设置为非零超时后,与此套接字关联的InputStream上的mySocket.setSoTimeout(2000);调用将仅在此时间量内阻塞。 如果超时到期,则会产生java.net.SocketTimeoutException,尽管套接字仍然有效。 必须先启用该选项,然后才能执行阻止操作。 超时必须大于0。零超时被解释为无限超时。
什么是SO_TIMEOUT?
套接字是连接的端点。 如果我说
mySocket.setSoTimeout(2000);
这是否意味着我要在2000毫秒内阻止从服务器/客户端为此套接字读取任何输入,并且在此时间之后套接字已准备好读取数据?
超时到期是什么意思?
阻止操作之前必须启用哪些选项?
无限超时意味着套接字不再读取?
3个解决方案
35 votes
这是否意味着我要在2000毫秒内阻止从服务器/客户端为此套接字读取任何输入,并且在此时间之后套接字已准备好读取数据?
不,这意味着如果在2000毫秒内没有数据到达,将抛出SocketTimeoutException。
超时到期是什么意思?
这意味着经过2000毫秒(对于您而言)没有任何数据到达。
阻止操作之前必须启用哪些选项?
没有一个“必须”启用。 如果您的意思是“可能已启用”,这就是其中之一。
套接字不再读取的无限超时状态?
真是个奇怪的建议。 这意味着,如果没有数据到达,则将永远阻止读取。
user207421 answered 2020-07-09T17:56:09Z
30 votes
JavaDoc很好地解释了它:
将此选项设置为非零超时后,将在 与此套接字关联的InputStream仅对此阻塞 多少时间。 如果超时到期,则 尽管Socket仍然存在,但引发了java.net.SocketTimeoutException 有效。 在进入阻止之前,必须启用该选项 操作才有效果。 超时必须大于0。超时为零 被解释为无限超时。
SO_TIMEOUT是read()呼叫将阻止的超时。 如果达到超时,将抛出java.net.SocketTimeoutException。 如果要永久阻止,请将此选项设置为零(默认值),则2959158711601857857538调用将一直阻止,直到可以读取至少1个字节为止。
logoff answered 2020-07-09T17:55:18Z
12 votes
这个例子让我很清楚:
如您所见,setSoTimeout阻止程序挂起! 等待SO_TIMEOUT时间! 如果没有任何信号,则抛出异常! 这意味着时间到期了!
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
public class SocketTest extends Thread {
private ServerSocket serverSocket;
public SocketTest() throws IOException {
serverSocket = new ServerSocket(8008);
serverSocket.setSoTimeout(10000);
}
public void run() {
while (true) {
try {
System.out.println("Waiting for client on port " + serverSocket.getLocalPort() + "...");
Socket client = serverSocket.accept();
System.out.println("Just connected to " + client.getRemoteSocketAddress());
client.close();
} catch (SocketTimeoutException s) {
System.out.println("Socket timed out!");
break;
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
public static void main(String[] args) {
try {
Thread t = new SocketTest();
t.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Bernard answered 2020-07-09T17:56:33Z