java为什么在不尝试I/O的情况下,不可能检测到TCPsocket被对等方正常关闭?
作为recent question的后续,我想知道为什么在Java中,如果不尝试在TCPsocket上读/写,就不可能检测到该socket已被对等方优雅地关闭?无论是使用前NIOSocket
还是NIOSocketChannel
,情况似乎都是这样
当对等方优雅地关闭TCP连接时,连接两侧的TCP堆栈都知道这一事实。服务器端(启动关机的那一方)最终处于状态^{Socket
或SocketChannel
中没有一个方法可以查询TCP堆栈以查看底层TCP连接是否已终止?是不是TCP堆栈不提供这样的状态信息?还是避免对内核进行代价高昂的调用是一种设计决策
在已经发布了这个问题的一些答案的用户的帮助下,我想我看到了问题可能来自哪里。未显式关闭连接的一方最终处于TCP状态CLOSE_WAIT
,这意味着连接正在关闭,并等待该方发出自己的CLOSE
操作。我认为isConnected
返回true
和isClosed
返回false
是很公平的,但是为什么没有类似isClosing
的东西呢
下面是使用NIO前socket的测试类。但使用NIO可以获得相同的结果
import java.net.ServerSocket;
import java.net.Socket;
public class MyServer {
public static void main(String[] args) throws Exception {
final ServerSocket ss = new ServerSocket(12345);
final Socket cs = ss.accept();
System.out.println("Accepted connection");
Thread.sleep(5000);
cs.close();
System.out.println("Closed connection");
ss.close();
Thread.sleep(100000);
}
}
import java.net.Socket;
public class MyClient {
public static void main(String[] args) throws Exception {
final Socket s = new Socket("localhost", 12345);
for (int i = 0; i < 10; i++) {
System.out.println("connected: " + s.isConnected() +
", closed: " + s.isClosed());
Thread.sleep(1000);
}
Thread.sleep(100000);
}
}
当测试客户端连接到测试服务器时,即使在服务器启动关闭连接后,输出仍保持不变:
connected: true, closed: false
connected: true, closed: false
...
共 (0) 个答案