简体   繁体   中英

What's the connection timeout of a socket created with a connecting constructor?

What's the connection timeout of a socket created with a connecting constructor?

In Java SE 6, the following constructors for Socket will connect the socket right away instead of you having to call connect on it after construction:

  • Socket(InetAddress address, int port)
  • Socket(InetAddress host, int port, boolean stream)
  • Socket(InetAddress address, int port, InetAddress localAddr, int localPort)
  • Socket(String host, int port)
  • Socket(String host, int port, boolean stream)
  • Socket(String host, int port, InetAddress localAddr, int localPort)

While it's nice and convenient and all that the Java SE folks created 500 ways of constructing a socket so you can just browse the list of 500 to find the one that sort of does what you want (instead of calling new Socket() followed by Socket#connect() ), none of the docs of these constructors says what the connection timeout is or whether/how they call connect(SocketAddress endpoint, int timeout) .

Perhaps the stuff in the constructor docs talking about createSocketImpl imply something about the timeout, or some docs somewhere else say it?

Anyone know what the actual connection timeout for any of these constructors is?


Background: Okay, assuming the spec is really ambiguous (I thought Java is portable?), I'm trying to figure out why a customer's code freezes at seemingly random times. I have some code that calls some open source library which calls one of these constructors. I want to know whether calling one of these constructors would have made the timeout infinite or very long. I don't know what version of the JDK the customer is using so it would be nice if the spec says the timeout somewhere. I guess I can probably get the JDK version from my customer, but it will probably be the closed source JDK. In that case, could I reverse-engineer the code in their version of the SE library to find out? Is it hard? Will I go to jail?

Even though Java docs says the timeout is infinite, it actually means that JVM will not impose any timeout on the connect operation, however OS is free to impose timeout settings on any socket operations.

Thus the actual timeout will be dependent on your OS's TCP/IP layer settings.

A good programming practice is to set timeouts for all socket operations, preferably configurable via configuration file. The advantage of having it configurable is that depending on the network load of the deployment environment, the timeout can be tweaked without re-building/re-testing/re-releasing the whole software.

Java spec is bogus. It doesn't say what timeout is on any of those constructor so implementation could set timeout to 0.000000000001 nanoseconds and still be correct. Furthurmore: non finite timeout not even respected by vm implementations (as seen here) so look like spec doesnt even matter cause noone followed it.

Conclusion: You have to read closed source binary of customer JVM (probably illegal but you have to do what you have to do), also OS socket doc.

查看code of Socket in OpenJDK 6-b14 ,您可以看到这些构造函数调用connect(socketAddress, 0) ,这意味着无限超时值。

According to the sources (I'm looking at 1.5_13 here, but there shouldn't be a difference), the different Socket constructors all call Socket(SocketAddress, SocketAddress, boolean) which is defined as:

private Socket(SocketAddress address, SocketAddress localAddr,
           boolean stream) throws IOException {
    setImpl();

    // backward compatibility
    if (address == null)
        throw new NullPointerException();

    try {
        createImpl(stream);
        if (localAddr == null)
        localAddr = new InetSocketAddress(0);
        bind(localAddr);
        if (address != null)
        connect(address);
    } catch (IOException e) {
        close();
        throw e;
    }
}

connect(SocketAddress) is defined as

public void connect(SocketAddress endpoint) throws IOException {
    connect(endpoint, 0);
}

Hence, infinite timeout (as @Keppil already stated).

The Socket class exists since Java 1.0, but at that time, it was only possible to create sockets, which were immediately connected and it was not possible to specify a connect timeout. Since Java 1.4, it has been possible to create unconnected sockets and then specify a timeout using the connect method. I assume that someone simply forgot to clarify the documentation of the "old" constructors, specifying that these still operate without an explicit timeout.

The documentation of the connect methods with timeout parameter reads that "a timeout of zero is interpreted as an infinite timeout". This is actually incorrect as well, since it only means that no timeout is implied by the Java VM. Even with a timeout of 0, the connect operation may still timeout in the operating system's TCP/IP stack.

It's platform-dependent but it's around a minute. The Javadoc for connect() is incorrect in stating that it is infinite. Note also that the connect() timeout parameter can only be used to decrease the default, not increase it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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