简体   繁体   English

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

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

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? 当我从ServerSocketChannel 接受()连接时,我保证返回的SocketChannel是“已连接 ”,或者可能发生返回的通道仍在执行某些形式的握手或其他任何情况,并且只会在以后设置其SelectionKey.OP_CONNECT位?

In other words, am I guaranteed that the following piece of code will never print false ? 换句话说,我保证下面的代码永远不会打印false吗?

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

According to the source of ServerSocketChannelImpl the ServerSocketChannelImpl creates a SocketChannelImpl with a state of ST_CONNECTED. 据的源ServerSocketChannelImplServerSocketChannelImpl创建SocketChannelImpl与ST_CONNECTED的状态。

Since the SocketChannelImpl.isConnected() method checks for a state of ST_CONNECTED, your test should always return true. 由于SocketChannelImpl.isConnected()方法检查ST_CONNECTED的状态,因此您的测试应始终返回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. 可能发生的是您的服务器线程被延迟,当您的线程调用isConnected() ,客户端已经关闭了连接。

So, no, there is no guarantee that your code will never print false. 所以,不,不能保证你的代码永远不会打印错误。

The state of SocketChannel and the underlying socket are independent until synchronized through a read/write operation. SocketChannel和底层套接字的状态是独立的,直到通过读/写操作同步。 There is no guarantee that the socket is still open after calling accept() . 调用accept()无法保证套接字仍处于打开状态。

So basically, SocketChannel.isConnected() is ALWAYS going to return TRUE after calling accept() but that is essentially a guess . 所以基本上, SocketChannel.isConnected() 总是在调用accept()之后返回TRUE ,但这实际上是猜测 It doesn't really know! 它真的不知道! The only way to test this is to try to read/write some data to the SocketChannel . 测试这个的唯一方法是尝试读取/写入一些数据到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; SocketChannel读取只会在read()返回-1时显示它已关闭;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM