When connecting to a server with a Java client socket I had this two different connection timeout exceptions.
Caused by: java.net.SocketTimeoutException: con
You will get a SocketTimeoutException
if you specify a timeout on connect(),
or if you've called setSoTimeout()
on a Socket
or ServerSocket
and a read()
or accept()
times out, respectively. In the case of connect(),
this is a serious problem: what you're trying to connect to either doesn't exist or is behind a firewall, and you can't tell which.
You will get connection refused
if the peer actively refused your connection request, which usually means there is nothing listening at the port you specified. Note that unlike a timeout, this means a response was received, and it was negative.
ConnectException is thrown on packet filter/firewall etc.
SocketTimeoutException is thrown when you have set a specific timeout on your socket, and it has not received anything before the timeout.
Example with a ServerSocket
:
ServerSocket serverSocket = new ServerSocket... // Create server socket
serverSocket.setSoTimeout(1000);
serverSocket.accept();
If the ServerSocket
has not received anything within 1000 ms it will throw a SocketTimeoutException
. Note that this exception is thrown for all sockets that use timeouts, not only ServerSocket
. This means that a Socket
object that throws a SocketTimeoutException
hasn't got anything back from the called server before the timeout.
To fix the problem you can either make sure that the server responds quicker, or set a higher timeout value.
Caused by: java.net.SocketTimeoutException: connect timed out
When you are not able to connect due to unavailability of the peer. Your second query, what about read? Than you will get
Caused by: java.net.SocketTimeoutException: Read timed out
Third possibility connection refused
if peer is active but refused the connection.
Also came here looking for the same answer, seemingly the docs can be easily misinterpreted:
Connects this socket to the server with a specified timeout value. A timeout of zero is interpreted as an infinite timeout. The connection will then block until established or an error occurs.
The key part that I overlooked in this is "an error"... going to the source I can see how Java's connect()
is actually invoking the Linux connect()
:
if (timeout <= 0) {
connect = connect(args...);
if (connect == -1 && errno == EINPROGRESS) {
connect = poll(args...);
// try again on EINTR
}
} else {
// Go to non-blocking mode for a timeout.
connect = connect(args...);
if (connect!=0) {
// not EINPROGRESS? -> throw ConnectException
while (!connect || !error || timedout) {
connect = poll(args...);
// error / timedout handling
}
if (timedout) {
// throw SocketTimeoutException
}
}
}
/* report the appropriate exception */
if (error) {
//EINVAL; throw SocketException
//EINTR; throw InterruptedIOException
//EPROTO; throw ProtocolException
//ECONNREFUSED;ETIMEDOUT; throw ConnectException
//EHOSTUNREACH; throw NoRouteToHostException
//EADDRNOTAVAIL; throw NoRouteToHostException
//EISCONN, EBADF, other; throw SocketException
}
i.e. I think SocketTimeoutException
is being thrown when the network is slow, or the host doesn't respond at all. Checking man connect
, I can see that ECCONNREFUSED
must be thrown when "No-one listening on the remote address", i.e. and an ICMP tells us so.
This means that if like me, you were trying to use the timeout
to connect to a (localhost) socket that wasn't ready to be connected to, you are SOL'd.