Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy is it impossible, without attempting I/O, to detect that TCP socket was gracefully closed by peer?
    text
    copied!<p>As a follow up to a <a href="https://stackoverflow.com/questions/151590/java-how-do-detect-a-remote-side-socket-close">recent question</a>, I wonder why it is impossible in Java, without attempting reading/writing on a TCP socket, to detect that the socket has been gracefully closed by the peer? This seems to be the case regardless of whether one uses the pre-NIO <code>Socket</code> or the NIO <code>SocketChannel</code>.</p> <p>When a peer gracefully closes a TCP connection, the TCP stacks on both sides of the connection know about the fact. The server-side (the one that initiates the shutdown) ends up in state <code>FIN_WAIT2</code>, whereas the client-side (the one that does not explicitly respond to the shutdown) ends up in state <code>CLOSE_WAIT</code>. Why isn't there a method in <code>Socket</code> or <code>SocketChannel</code> that can query the TCP stack to see whether the underlying TCP connection has been terminated? Is it that the TCP stack doesn't provide such status information? Or is it a design decision to avoid a costly call into the kernel?</p> <p>With the help of the users who have already posted some answers to this question, I think I see where the issue might be coming from. The side that doesn't explicitly close the connection ends up in TCP state <code>CLOSE_WAIT</code> meaning that the connection is in the process of shutting down and waits for the side to issue its own <code>CLOSE</code> operation. I suppose it's fair enough that <code>isConnected</code> returns <code>true</code> and <code>isClosed</code> returns <code>false</code>, but why isn't there something like <code>isClosing</code>?</p> <p>Below are the test classes that use pre-NIO sockets. But identical results are obtained using NIO.</p> <pre><code>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 &lt; 10; i++) { System.out.println("connected: " + s.isConnected() + ", closed: " + s.isClosed()); Thread.sleep(1000); } Thread.sleep(100000); } } </code></pre> <p>When the test client connects to the test server the output remains unchanged even after the server initiates the shutdown of the connection:</p> <pre><code>connected: true, closed: false connected: true, closed: false ... </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload