简体   繁体   English

Java setSoTimeout 不适用于 Windows

[英]Java setSoTimeout Not Working on Windows

I am attempting to set a socket timeout on a Java application.我正在尝试在 Java 应用程序上设置套接字超时。 Some of the developers are on OS X, others are on Windows.一些开发人员使用 OS X,其他开发人员使用 Windows。 The issue is on Windows machines we get a SocketException: Connection reset after exactly 2 minutes, regardless of what the timeout is set to.问题是在 Windows 机器上,无论超时设置为多少,我们都会收到 SocketException: Connection reset after just 2 分钟。 However on OS X it works exactly as expected.但是在 OS X 上它完全按预期工作。

It seems like this is specifically an issue with how the JVM is interacting with the underlying Windows socket libraries.这似乎是 JVM 如何与底层 Windows 套接字库交互的具体问题。 Is there anyway to address this issue.有没有办法解决这个问题。

Here is a snippet of code that creates the socket.这是创建套接字的代码片段。

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;
  }

The code calling openSocket is then calling read on the socket returned.然后调用 openSocket 的代码在返回的套接字上调用 read。

Read timeouts don't cause connection resets.读取超时不会导致连接重置。 They cause SocketTimeoutExceptions (in Java).它们会导致SocketTimeoutExceptions (在 Java 中)。

A connection reset is therefore not evidence that setting the read tiemout isn't working.因此,连接重置并不能证明设置读取超时无效。 It might be evidence of something else, for example a firewall rule.它可能是其他东西的证据,例如防火墙规则。

Your conjecture is false.你的猜想是错误的。

The issue was the following code in the calling method问题是调用方法中的以下代码

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();
  }

This caused FIN_WAIT to be sent, and it appears Windows kills sockets in that status automatically after two minutes.这导致 FIN_WAIT 被发送,看起来 Windows 会在两分钟后自动终止处于该状态的套接字。 Then when the read occurred it caused a SocketException: Connection reset.然后,当读取发生时,它会导致 SocketException: Connection reset。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM