0

I'm trying to connect to a remote host trying over and over waiting for it to come up. However, after one shot with a Connection Refused exception (because the server isn't running yet), it throws Socket closed exception continuously. Why would the socket be closed? The socket should simply be in the same state as it was before the failed connect() call, shouldn't it?

                while(!tcpSock.isConnected()) {
                    try {
                        tcpSock.connect(destination);
                    } catch (SocketException e) {
                        System.err.println(e.toString());
                    }
                }

results in

Setting TCP client mode connecting to remote host localhost/127.0.0.1 port 4500
java.net.ConnectException: Connection refused: connect
java.net.SocketException: Socket closed
java.net.SocketException: Socket closed
java.net.SocketException: Socket closed
java.net.SocketException: Socket closed

Desired behavior is

Setting TCP client mode connecting to remote host localhost/127.0.0.1 port 4500
java.net.ConnectException: Connection refused: connect
java.net.ConnectException: Connection refused: connect
java.net.ConnectException: Connection refused: connect
java.net.ConnectException: Connection refused: connect
Established connection to: localhost port 4500

(Once I'm done debugging, I'll comment out the print of the exception.)

1 Answer 1

2

Looking at the OpenJDK source code ... when the connect(...) call fails, the SocketImpl code calls close() on the Socket.

This is the code in Java 11 (in java.net.AbstractPlainSocketImpl):

protected void connect(String host, int port)
    throws UnknownHostException, IOException
{
    boolean connected = false;
    try {
        InetAddress address = InetAddress.getByName(host);
        this.port = port;
        this.address = address;

        connectToAddress(address, port, timeout);
        connected = true;
    } finally {
        if (!connected) {
            try {
                close();  // <<---- HERE
            } catch (IOException ioe) {
                /* Do nothing. If connect threw an exception then
                   it will be passed up the call stack */
            }
        }
    }
}

That close() call on the SocketImpl object leads to the Socket being marked as closed.


In short, a Java Socket object does not support retrying after a failed connection attempt. If you want to retry, your code needs to create a new Socket object.

Discussion of whether it is correct for Socket to behave this way is beside the point. It just does ... and it is highly unlikely that this will ever change. The only thing that might change is that they might document this behavior in the Socket javadocs.

Sign up to request clarification or add additional context in comments.

1 Comment

Yep, an API is what it is. Thanks, wanted to make sure I wasn't doing something wrong. Took me all of 5 minutes to expand the while loop upwards to create a fresh socket each time once you explained it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.