Java setSoTimeout在Windows上不起作用

时间:2016-09-29 18:49:20

标签: java sockets jvm

我正在尝试在Java应用程序上设置套接字超时。一些开发人员在OS X上,其他人在Windows上。问题是在Windows机器上我们得到SocketException:连接重置2分钟后,无论超时设置为什么。但是在OS X上它的工作方式完全符合预期。

这似乎是JVM如何与底层Windows套接字库交互的一个问题。无论如何都要解决这个问题。

以下是创建套接字的代码片段。

protected Socket openSocket() throws UnknownHostException, IOException {

    Socket socket = new Socket();
    SocketAddress endpoint = new InetSocketAddress( this.getHost(), this.getPort() );
    try {
      if ( this.getConnectTimeout() != null ) {
        socket.connect( endpoint, this.getConnectTimeout() );
      } else {
        socket.connect( endpoint );
      }
    } catch ( ConnectException ex ) {
      throw ex;
    } catch ( IOException ex ) {
      ConnectException connEx = new ConnectException( 
          String.format( "Failed to connect to service at %s:%d. Reason: %s", 
              this.getHost(), this.getPort(), ex.getMessage() ) );
      connEx.initCause( ex );
      throw connEx; 
    }

    logger.debug( "Socket opened to {}:{}", this.getHost(), this.getPort() );

    if ( this.getResponseTimeout() != null ) {
      socket.setSoTimeout( this.getResponseTimeout() );
    }

    return socket;
  }

调用openSocket的代码然后在返回的套接字上调用read。

2 个答案:

答案 0 :(得分:-1)

读取超时不会导致连接重置。它们导致SocketTimeoutExceptions(在Java中)。

因此,连接重置不是设置读取tiemout不起作用的证据。它可能是其他东西的证据,例如防火墙规则。

你的推测是错误的。

答案 1 :(得分:-1)

问题是调用方法

中的以下代码
StringBuffer responseText = new StringBuffer();
try (Socket socket = openSocket();
        OutputStream os = socket.getOutputStream();
        PrintStream psOut = new PrintStream(os, true);
        BufferedReader inReader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));) {
  logger.trace("Opened socket");
  try {
    psOut.println(requestXML);
  } finally {
      socket.shutdownOutput();
  }

这导致FIN_WAIT被发送,并且看起来Windows在两分钟后自动杀死处于该状态的套接字。然后,当发生读取时,它导致SocketException:Connection reset。