setSoTimeout的功能是什么以及它如何工作?

时间:2012-10-10 13:46:16

标签: java networking connection

我正在尝试自己学习Socket。关注Oracle网站上的文字我有点困惑。我对此有一些疑问。提前感谢任何明确的解释。

  

setSoTimeout

     

public void setSoTimeout(int timeout)抛出SocketException

     

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

  1. 什么是SO_TIMEOUT?
  2. Socket是连接的端点。如果我说

    mySocket.setSoTimeout(2000);
    

    这是否意味着我阻止从服务器/客户端读取此套接字的任何输入2000毫秒,在此之后套接字已准备好读取数据?

  3. 超时到期是什么意思?

  4. 在阻止操作之前必须启用哪个选项?

  5. 无限超时意味着套接字不再读取?

3 个答案:

答案 0 :(得分:33)

  

这是否意味着我阻止从服务器/客户端读取此套接字的任何输入2000毫秒,在此之后套接字已准备好读取数据?

不,这意味着如果没有数据在2000毫秒内到达,将会抛出SocketTimeoutException

  

超时到期是什么意思?

这意味着2000ms(在您的情况下)经过而没有任何数据到达。

  

在阻止操作之前必须启用哪个选项?

没有一个'必须'启用。如果您的意思是“可能已启用”,则这是其中之一。

  

套接字不再读取的无限超时措辞?

多么奇怪的建议。这意味着如果没有数据到达,您将永远阻止读取。

答案 1 :(得分:29)

JavaDoc解释得非常好:

  

将此选项设置为非零超时,对()调用read()   与此Socket关联的InputStream将仅阻止此操作   多少时间。如果超时到期,a   引发了java.net.SocketTimeoutException,尽管Socket仍然存在   有效。必须在进入阻止之前启用该选项   操作有效。超时必须> 0.超时为零   被解释为无限超时。

SO_TIMEOUTread()调用阻止的超时时间。如果达到超时,将抛出java.net.SocketTimeoutException。如果要永久阻止将此选项置为零(默认值),则read()调用将阻塞,直到至少可以读取1个字节。

答案 2 :(得分:12)

这个例子让我一切都清楚:
如您所见,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();
    }
  }
}