我在端口8888中有一个ServerSocketChannel和一个Socket.ServerSocket绑定。 套接字连接到ServerSocket并发送数据。如果我只关闭了ServerSocket,TCP仍然是ESTABLISHED。如果我只关闭Socket,则没有任何ESTABLISHED。
我使用以下代码关闭ServerSocketChannel:
public void doStop() {
try {
acceptChannel.close(); //close ServerSocketChannel
acceptChannel.socket().close(); //close ServerSocket
LOG.debug("close server socket. " + acceptChannel.socket().isClosed());
} catch (IOException ignore) {}
try { selector.close(); } catch (IOException ignore) {}
}
这里有两个TCP状态。
1.在我关闭ServerSocket:
之前zephyrdeiMac:~ zephyrguo$ lsof -i tcp:8888 -n
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 26272 zephyrguo 17u IPv4 0x5f7a02f802ab0c75 0t0 TCP *:ddi-tcp-1 (LISTEN)
java 26272 zephyrguo 40u IPv4 0x5f7a02f802b07715 0t0 TCP 127.0.0.1:52728->127.0.0.1:ddi-tcp-1 (ESTABLISHED)
java 26272 zephyrguo 41u IPv4 0x5f7a02f7f9669ff5 0t0 TCP 127.0.0.1:ddi-tcp-1->127.0.0.1:52728 (ESTABLISHED)
2.关闭ServerSocket后:
zephyrdeiMac:~ zephyrguo$ lsof -i tcp:8888 -n
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
java 26272 zephyrguo 40u IPv4 0x5f7a02f802b07715 0t0 TCP 127.0.0.1:52728->127.0.0.1:ddi-tcp-1 (ESTABLISHED)
java 26272 zephyrguo 41u IPv4 0x5f7a02f7f9669ff5 0t0 TCP 127.0.0.1:ddi-tcp-1->127.0.0.1:52728 (ESTABLISHED)
ESTABLISHED仍在此处,但没有LISTEN.Socket可以发送数据,但没有响应。
答案 0 :(得分:1)
关闭ServerSocketChannel
不会以任何方式影响已建立的连接。您的期望不正确。
ServerSocketChannel
注册的SocketChannel
或Selector
在close()
之后保持打开状态,直到您下次致电select()
为止。您可以致电selectNow()
强制执行此操作。这是在Javadoc的某处记录的,当我寻找它时我永远找不到它。他们使用dup()
做了一些技巧,以确保您不再使用SocketChannel
,但Selector
不会中断。