8

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.

Timwi
  • 65,159
  • 33
  • 165
  • 230
aryaxt
  • 76,198
  • 92
  • 293
  • 442
  • I'm confused somebody keeps changing the title of my questions. What's going on here? – aryaxt Aug 14 '10 at 20:44
  • With the above code you're checking if the SocketChannel is still connected. So what exactly have you been testing, the Socket, as mentioned in your question or the channel as described in the title and shown in the code? Just asking, because people started downvoting my answer... (without explaining why...) – Andreas Dolk Aug 15 '10 at 20:08
  • 1
    1- You manually close the socket, by calling the method, that's why you get false after you disconnected from the server, in my case i am trying to detect if there was a disconnection issue, for instance "connection loss", so the socket won't detect that it's disconnected unless i try to send a message to the server and get an exception. 2- I also mentioned that i am using a selector. so isConnected method doesn't show if i am connected to the server or not, but it shows if my socket is still connected to the selector or not, which returns true as long as my socket is connected to the selector – aryaxt Aug 17 '10 at 02:48

3 Answers3

12

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
  • 44,725
  • 9
  • 65
  • 93
7

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 Dolk
  • 113,398
  • 19
  • 180
  • 268
  • 2
    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 Dolk Aug 15 '10 at 20:04
  • 1
    I agree with Andreas: unexplained downvotes are useless, or worse. I am coming to regard unexplained downvotes as mere site vandalism. – user207421 Sep 23 '12 at 23:31
4

isConnected() tells you whether you have connected the channel object, which you have, and it's not specified to return false after you close it, although apparently it does: see Andreas's answer. 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.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • `isConnected()` returns `false` on my machine when I close the channel to the remote server. See my answer for a working example. – Andreas Dolk Aug 15 '10 at 08:27
  • `-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 Dolk Aug 15 '10 at 08:32
  • 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. – user207421 Aug 15 '10 at 08:35