1

This is a pretty basic question, but I can't find a definitive answer for it anywhere:

When I accept() a connection from a ServerSocketChannel, am I guaranteed that the returned SocketChannel is "connected", or could it happen that the returned channel is still performing some form a handshake or whatever and will only later set its SelectionKey.OP_CONNECT bit?

In other words, am I guaranteed that the following piece of code will never print false?

ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress(1234));
SocketChannel socketChannel = serverSocketChannel.accept();
System.out.println(socketChannel.isConnected());
Markus A.
  • 12,349
  • 8
  • 52
  • 116
  • _If this channel is in non-blocking mode then this method will immediately return null if there are no pending connections. Otherwise **it will block indefinitely until a new connection** is available or an I/O error occurs._ seems to indicate it will be connected. – Sotirios Delimanolis Jun 27 '16 at 16:49
  • @SotiriosDelimanolis "Seems to" is exactly the problem! ;) A connection might already be considered "available" before it is completely "connected". Maybe... I don't know... I wish they were more clear on this... – Markus A. Jun 27 '16 at 16:55

2 Answers2

3

According to the source of ServerSocketChannelImpl the ServerSocketChannelImpl creates a SocketChannelImpl with a state of ST_CONNECTED.

Since the SocketChannelImpl.isConnected() method checks for a state of ST_CONNECTED, your test should always return true.

That is however the scenario for the good times. What could happen is that your server thread gets delayed and by the time your thread calls isConnected() the client already closed the connection.

So, no, there is no guarantee that your code will never print false.

Thomas Kläger
  • 17,754
  • 3
  • 23
  • 34
1

The state of SocketChannel and the underlying socket are independent until synchronized through a read/write operation. There is no guarantee that the socket is still open after calling accept().

So basically, SocketChannel.isConnected() is ALWAYS going to return TRUE after calling accept() but that is essentially a guess. It doesn't really know! The only way to test this is to try to read/write some data to the SocketChannel.

Writing data to the channel will reveal if the socket is still open on the remote computer. You can test this behavior by connecting client and server using a switch then removing a networking cable of one of the computers. You will see how the sockets will stay open for a very long time. There are some socket options that can be used to mitigate this but not by much.

Reading from the SocketChannel will only reveal that it is closed if read() returns -1;

Johnny V
  • 795
  • 5
  • 14