ServerSocketChannel.accept()返回的SocketChannel是否保证连接?

Is the SocketChannel returned by ServerSocketChannel.accept() guaranteed to be connected?

这是一个非常基本的问题,但我在任何地方都找不到明确的答案:

当我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位?

换句话说,我是否保证下面的代码永远不会打印false?

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

根据 ServerSocketChannelImpl the ServerSocketChannelImpl creates a SocketChannelImpl 的来源,状态为 ST_CONNECTED。

由于 SocketChannelImpl.isConnected() 方法检查状态 ST_CONNECTED,您的测试应始终 return 为真。

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

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

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

所以基本上,SocketChannel.isConnected()总是 在调用 accept() 之后 return TRUE但这本质上是 猜测。它真的不知道!测试这个的唯一方法是尝试 read/write 一些数据到 SocketChannel.

向通道写入数据将显示远程计算机上的套接字是否仍处于打开状态。您可以通过使用交换机连接客户端和服务器然后移除其中一台计算机的网络电缆来测试此行为。您将看到套接字如何长时间保持打开状态。有一些套接字选项可用于缓解这种情况,但影响不大。

如果 read() returns -1;

,从 SocketChannel 读取只会显示它已关闭