Summary
An @apiNote
is added to the javadoc of java.net.Socket.connect(SocketAddress endpoint, int timeout)
to explain that a java.net.SocketTimeoutException
is raised only when the given timeout
expires before any other connection errors, including operating system specific connect timeout, occur.
Problem
The connect(SocketAddress endpoint, int timeout)
method on Socket
takes a timeout
value which is considered to be the maximum amount of time to wait for a successful connection. This method specifies that a SocketTimeoutException
is thrown if the timeout
expires before connecting.
Several factors play a role in establishing a TCP/IP connection, including connection timeout that is imposed by the operating system. If the operating system timeout occurs before the user supplied timeout
to this method, then this method throws an IOException
, which can resemble:
Exception in thread "main" java.net.ConnectException: Operation timed out
at java.base/sun.nio.ch.Net.connect0(Native Method)
at java.base/sun.nio.ch.Net.connect(Net.java:589)
at java.base/sun.nio.ch.Net.connect(Net.java:578)
at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:583)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327)
at java.base/java.net.Socket.connect(Socket.java:751)
Users find it surprising that the connect operation that failed, due to the operating system timeout, throws IOException
instead of SocketTimeoutException
.
The timeout
parameter to the Socket.connect()
method has always been an usability feature to prevent applications hanging for a long time. It was never meant to override the operating system timeout, whose value might be lower than what the users pass to this method. The current documentation of this method however doesn't provide this guidance to developers thus resulting in confusion about the semantics of this method.
Solution
An @apiNote
is added to explain how the operating system connect timeout may play a role in what exception gets thrown from this method.
Specification
diff --git a/src/java.base/share/classes/java/net/Socket.java b/src/java.base/share/classes/java/net/Socket.java
+ * @apiNote Establishing a TCP/IP connection is subject to connection timeout settings
+ * in the operating system. The typical operating system timeout is 60 seconds. If the
+ * operating system timeout expires before the {@code timeout} specified to this method
+ * then an {@code IOException} is thrown. The {@code timeout} specified to this method
+ * is typically a timeout value that is shorter than the operating system timeout.
+ *
* @param endpoint the {@code SocketAddress}
* @param timeout the timeout value to be used in milliseconds.
* @throws IOException if an error occurs during the connection, the socket
public void connect(SocketAddress endpoint, int timeout) throws IOException {
- csr of
-
JDK-7116990 (spec) Socket.connect(addr,timeout) not clear if IOException because of TCP timeout
-
- Open
-