views:

67

answers:

3

I have a socket running, using selectors. I am trying to check to see if my socket is connected to the server or not.

Boolean connected = _channel.isConnected();

and it always returns true. I turned off Airport (internet connection) on my computer, and when i check to see if the socket is connected or not, it still returns true. Any idea why? I try to write data to the server every 3 seconds, and it still doesn't change the state of my socket to disconnected.

A: 

A socket channel can be connected by invoking its connect method; once connected, a socket channel remains connected until it is closed.

The channel is not closed when the server is not available anymore, due to a broken physical connection or a server failure. So once a connection has been established, isConnected() will be returning true until you close the channel on your side.

If you want to check, if the server is still available, send a byte to the sockets outputstream. If you get an Exception, then the server is unavailable (connection lost).


Edit

for EJP - some code to test and reconsider your comment and answer:

public class ChannelTest {
     public static void main(String[] args) throws UnknownHostException, IOException {
      Socket google = new Socket(InetAddress.getByName("www.google.com"), 80);
      SocketChannel channel = SocketChannel.open(google.getRemoteSocketAddress());
      System.out.println(channel.isConnected());
      channel.close();
      System.out.println(channel.isConnected());
    }
}

Output on my machine is

true
false
Andreas_D
Incorrect, it doesn't change when you close it.
EJP
Hmm, must be different for channels, it's certainly true for sockets, or else I am crazy, always a possibility.
EJP
Dear downvoters - please leave a comment, if you think the answer is not helpful. At least EJP comment is incorrect as his answer... The question was about SocketChannels and I'm still sure, this explains, why turning off the airport does not result in an `isConnected() == false`.
Andreas_D
+3  A: 

Usually if you turn off OS level networking, writes to socket should throw exceptions, so you know the connection is broken.

However more generally, we cann't be sure if a packet is delivered. In java (probably C too), there is no way to check if a packet is ACK'ed.

Even if we can check TCP ACKs, it doesn't guarantee that the server received or processed the packet. It only means that the target machine received the packet and buffered it in memory. Many things can go wrong after that.

So if you really want to sure, you can't rely on transport protocol. You must have application level ACK, that is, the server application writes back an ACK message after it received and processed a message from client.

From client point of view, it writes a message to server, then tries to read ACK from server. If it gets it, it can be certain that its message is received and processed. If it fails to get ACK, well, it has no idea what has happened. Empirically, most likely TCP failed. Next possiblity is that server crashed. It's also possible that everything went OK, except the ACK couldn't reach the client.

irreputable
it doesn't throw any exception, i remember in C# wheen there is no connection it throws an exception while reading, or writing. This is not the case in java :(
aryaxt
A: 

isConnected() tells you whether you have connected the channel object, which you have, and it remains true even after you close it. It's not there to tell you whether the underlying connection is still there. You can only tell that by using it: -1 from a read, or an exception, tells you that.

EJP
`isConnected()` returns `false` on my machine when I close the channel to the remote server. See my answer for a working example.
Andreas_D
`-1` from read doesn't work too. I added a read and it blocked (waiting for bytes). Then I pulled the network cable and the application kept blocking (no `-1` as a result).
Andreas_D
Yes, -1 from read detects an orderly close. The only way to detect a disorderly close with a read and no writes is via a read timeout, which delivers an exception.
EJP