Eagle
Eagle

Reputation: 1074

java.net.ConnectException: Connection refused timeout

I saw a lot of "java.net.ConnectException: Connection refused" questions but none referring to timeout of this error. My problem is I have to connect to a server that, in some cases, is blocked (connected by another software to the same port). So, I'm doing a loop with some max retries to try to connect:

My current code (of course, is depending on a lot of configurations for my software, but is working fine):

    public TCPConnector(TCPDefinition tcpDefinition) throws IAException {
    ivTcpDefinition = tcpDefinition;
     // Initialize the socket
    boolean retry = false;
    int counter = 1;
    do {
        try {
            ivSocket = new Socket();
            ivSocket.connect(new InetSocketAddress(tcpDefinition.getHostname(), tcpDefinition.getPort()), tcpDefinition.getConnectTimeOut());
            ivSocket.setSoTimeout(tcpDefinition.getAckTimeOut());
            retry = false;
        }
        catch (UnknownHostException uhe) {
            throw new IAException(null, new StringBuffer("Can't find host: ").append(tcpDefinition.getHostname()).toString(), uhe);
        }
        catch (SocketException see) {
            StringBuilder sb = new StringBuilder("Connection refused to host ").append(tcpDefinition.getHostname()).
            append(" port ").append(tcpDefinition.getPort()).append(". Connection Attempt Nr. ").append(counter);
            logger.error(sb.toString(), see);
            retry = true;
            if (counter++ > tcpDefinition.getConnectRetries())
                throw new IAException(null, sb.toString(), see);
            else
                logger.error("will retry to connect");
        }
        catch (IOException ioe) {
            StringBuilder sb = new StringBuilder("I/O error while connecting to host ").append(tcpDefinition.getHostname()).
            append(" port ").append(tcpDefinition.getPort()).append(". Connection Attempt Nr. ").append(counter);
            logger.error(sb.toString(), ioe);
            retry = true;
            if (counter++ > tcpDefinition.getConnectRetries())
                throw new IAException(null, sb.toString(), ioe);
            else
                logger.error("will retry to connect");
        }
    }
    while (retry);

}

Well, the problem is this:

Windows:

2019-12-05 12:40:47,609 ERROR DefaultQuartzScheduler_Worker-1 TCPConnector - Connection refused to host localhost port 13002. Connection Attempt Nr. 1 java.net.ConnectException: Connection refused: connect at java.net.PlainSocketImpl.socketConnect(Native Method)

2019-12-05 12:40:48,703 ERROR DefaultQuartzScheduler_Worker-1 TCPConnector - Connection refused to host localhost port 13002. Connection Attempt Nr. 2 java.net.ConnectException: Connection refused: connect

Linux:

2019-12-05 12:45:47,609 ERROR DefaultQuartzScheduler_Worker-1 TCPConnector - Connection refused to host localhost port 13002. Connection Attempt Nr. 1 java.net.ConnectException: Connection refused: connect at java.net.PlainSocketImpl.socketConnect(Native Method)

2019-12-05 12:45:47,610 ERROR DefaultQuartzScheduler_Worker-1 TCPConnector - Connection refused to host localhost port 13002. Connection Attempt Nr. 2 java.net.ConnectException: Connection refused: connect

Why the timeout is not executed? Well this is not exactly right. If I configure a timeout less than 1 second on Windows, then the timeout is executed. 500 msec:

2019-12-05 11:47:07,375 ERROR DefaultQuartzScheduler_Worker-1 TCPConnector - I/O error while connecting to host localhost port 13002. Connection Attempt Nr. 1 java.net.SocketTimeoutException: connect timed out at java.net.PlainSocketImpl.socketConnect(Native Method)

2019-12-05 11:47:07,875 ERROR DefaultQuartzScheduler_Worker-1 TCPConnector - I/O error while connecting to host localhost port 13002. Connection Attempt Nr. 2 java.net.SocketTimeoutException: connect timed out at java.net.PlainSocketImpl.socketConnect(Native Method)

It is possible to configure a "connect refuse" timeout?

Upvotes: 0

Views: 9541

Answers (1)

Stephen C
Stephen C

Reputation: 718678

There is no such thing as a "connection refused timeout".

"Connection refused" happens when the server sees the connection request, but there is no service listening for connections on the IP + port that the request is directed to. The server then "refuses" the connection. This typically happens instantly, so so no timeout is triggered.

"Connection timed out" happens (typically) when something stops the connection request from reaching the server1, 2. So the client-side will wait for the response from the server, and then resend / wait a few times. And eventually the time allotted for establishing a connection will expire ... and the connection times out.

As you can see these are different scenarios. And they are reported back to the Java client-side differently.

So the reason you are not getting timeouts is that the "connection refused" responses are coming back quick enough that your configured timeout is not exceeded.

That might also explain why setting the connect timeout small might have changed the behavior. There may also be issues with the granularity of the timeout that the OS allows Java to set.

To investigate this further, I think we would need a minimal reproducible example. For example, we need to see how you have implemented the code that manages the server-socket and accepts connections on the server side.


1 - The blockage could be on the server's reply packets.
2 - There are various possible causes for this kind of thing. The most likely are a firewall blocking traffic somewhere, a network routing problem, or using a private IP address on the wrong network.

Upvotes: 3

Related Questions