有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java为什么在不尝试I/O的情况下,不可能检测到TCPsocket被对等方正常关闭?

作为recent question的后续,我想知道为什么在Java中,如果不尝试在TCPsocket上读/写,就不可能检测到该socket已被对等方优雅地关闭?无论是使用前NIOSocket还是NIOSocketChannel,情况似乎都是这样

当对等方优雅地关闭TCP连接时,连接两侧的TCP堆栈都知道这一事实。服务器端(启动关机的那一方)最终处于状态^{,而客户端(没有明确响应关机的那一方)最终处于状态^{)。为什么在SocketSocketChannel中没有一个方法可以查询TCP堆栈以查看底层TCP连接是否已终止?是不是TCP堆栈不提供这样的状态信息?还是避免对内核进行代价高昂的调用是一种设计决策

在已经发布了这个问题的一些答案的用户的帮助下,我想我看到了问题可能来自哪里。未显式关闭连接的一方最终处于TCP状态CLOSE_WAIT,这意味着连接正在关闭,并等待该方发出自己的CLOSE操作。我认为isConnected返回trueisClosed返回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) 个答案