2016-06-27 52 views
1

这是一个非常基本的问题,但我不能为它找到任何地方一个明确的答案:ServerSocketChannel.accept()返回的SocketChannel是否保证连接?

当我accept()从的ServerSocketChannel的连接,我是保证返回的SocketChannel是“connected”,或可能呢发生返回的频道仍在执行某种形式的握手或其他任何操作,只会稍后将其设置为SelectionKey.OP_CONNECT位?

换句话说,我是保证,下面的代码片段将从未打印false

ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); 
serverSocketChannel.socket().bind(new InetSocketAddress(1234)); 
SocketChannel socketChannel = serverSocketChannel.accept(); 
System.out.println(socketChannel.isConnected()); 
+0

_如果此通道处于非阻塞模式,那么如果没有挂起的连接,此方法将立即返回null。否则,**将无限期阻止,直到出现新的连接**或发生I/O错误。似乎表明它将被连接。 –

+0

@SotiriosDelimanolis“似乎”正是这个问题! ;)连接在完全“连接”之前可能已被视为“可用”。也许......我不知道......我希望他们对此更加清楚...... –

回答

3

ServerSocketChannelImplServerSocketChannelImpl源创建具有ST_CONNECTED的状态的SocketChannelImpl

由于SocketChannelImpl.isConnected()方法检查ST_CONNECTED状态,所以测试应始终返回true。

然而,这是美好时光的情景。可能发生的情况是,服务器线程被延迟,并且在线程调用isConnected()时,客户端已关闭连接。

所以,不,不能保证你的代码永远不会打印错误。

+0

看起来不错。谢谢! +1,√ –

0

SocketChannel和底层套接字的状态是独立的,直到通过读/写操作同步为止。有不能保证插座仍然打开后调用accept()

所以基本上,SocketChannel.isConnected()总是去调用accept()后返回TRUE 但本质上是一个猜测。它并不真正知道!测试这个的唯一方法是尝试读取/写入一些数据到SocketChannel

将数据写入通道将显示套接字是否仍在远程计算机上打开。您可以通过使用交换机连接客户端和服务器,然后移除其中一台计算机的网络电缆来测试此行为。你会看到插座将会很长时间保持打开状态。有一些套接字选项可以用来缓解这一点,但不是太多。

SocketChannel中读取只显示,如果read()返回-1,它将被关闭;

相关问题