How can a socket be both connected and closed?
Asked Answered
B

1

32

I'm using a Java socket client. In a case where the server is still connected to my client but it does not send a response to my message - I eventually get a read time out exception.

In that case I want to test to see if I should reconnect my socket or just keep it an re-use it.

I use this condition:

if (!socket.isConnected() || socket.isClosed() || !socket.isBound()) {
    try {
        socket.close();
    } catch (IOException e1) {
    }
    // Wait on a new connection
    socket = connectSocket(.....);
}

But I always seem to reconnect. When I log the values of the Boolean properties I see this:

connected: true closed: true bound: true

How can it be connected and closed?

TIA

Blayze answered 13/9, 2010 at 13:54 Comment(2)
Method calls are not atomic... perhaps another thread is closing the socket between the isConnected() and isClosed() calls? Perhaps synchronize on the socket object first?Dickson
That's easy to test if you just reverse the order of the checks for isConnected() and isClosed().Festoonery
M
85

This thread has some useful discussions on this topic. It turns out that Socket.isConnected returns true if it has (ever) been successfully connected.

From the above thread:

When you use Socket(), which you seem to have overlooked, Socket.isConnected() tells you whether Socket.connect() has been called or not. Similarly for isClosed() and close().

Confusion over these methods results from confusing the state of the socket, which is under the control of the application, with the state of the overall connection, which is under the control of the protocol. isConnected() and isClosed() tell what you have done to the socket. There are no APIs other than read and write for determining the state of the connection.

The docs says:

Returns true if the socket successfuly connected to a server

and not as one perhaps would expect "returns true if the socket is connected to a server".

The behavior can be confirmed by looking at the source of Socket:

public boolean isConnected() {
    // Before 1.3 Sockets were always connected during creation
    return connected || oldImpl;
}

You could also run this little test snippet:

Socket s = new Socket();

System.out.println("isConnected: " + s.isConnected() +
                  " isBound: "     + s.isBound() +
                  " isClosed: "    + s.isClosed());

s.connect(new InetSocketAddress("google.com", 80));

System.out.println("isConnected: " + s.isConnected() +
                   " isBound: "    + s.isBound() +
                   " isClosed: "   + s.isClosed());

s.close();

System.out.println("isConnected: " + s.isConnected() +
                   " isBound: "    + s.isBound() +
                   " isClosed: "   + s.isClosed());

Which prints:

isConnected: false isBound: false isClosed: false
isConnected: true isBound: true isClosed: false
isConnected: true isBound: true isClosed: true

I must say that the documentation is quite unclear on this point, and that the method-name is a bit misleading.

Manure answered 13/9, 2010 at 14:15 Comment(2)
Broken link, but from the quotations it appears to have been lifted holus-bolus from answers either here or at the Sun/Oracle Java Forums, many of them by me.Misogyny
Nice answer. I had also confusion for isConnected.Marguerite

© 2022 - 2024 — McMap. All rights reserved.