최근 질문에 대한 후속 으로, TCP 소켓에서 읽기 / 쓰기를 시도하지 않고 Java에서 소켓이 피어에 의해 정상적으로 닫 혔음을 감지하는 것이 왜 불가능한지 궁금합니다. 이 관계없이 하나가 사전 NIO 사용하는지 여부의 경우 것 같다 Socket
또는 NIO SocketChannel
.
피어가 TCP 연결을 정상적으로 닫으면 연결 양쪽의 TCP 스택이 그 사실을 알고 있습니다. 서버 측 (종료를 시작하는 서버)은 state에서 끝나는 FIN_WAIT2
반면 클라이언트 측 (종료에 명시 적으로 응답하지 않는 서버)은 state에서 끝납니다 CLOSE_WAIT
. 왜의 방법이 아닌 Socket
또는 SocketChannel
기본 TCP 연결이 종료되었는지 여부를 확인하기 위해 즉, TCP 스택을 조회 할 수는? TCP 스택이 그러한 상태 정보를 제공하지 않는 것입니까? 아니면 비용이 많이 드는 커널 호출을 피하기위한 설계 결정입니까?
이 질문에 대한 답변을 이미 게시 한 사용자의 도움으로 문제의 원인을 알 수 있다고 생각합니다. 연결을 명시 적으로 닫지 않은 쪽은 TCP 상태 CLOSE_WAIT
가되어 연결이 종료되는 과정에 있으며 쪽이 자체 CLOSE
작업 을 실행할 때까지 기다립니다 . 나는 그것이 isConnected
반환 true
하고 isClosed
반환 하는 것이 충분히 공정하다고 생각 false
하지만, 왜 그런 것이 isClosing
없는가?
다음은 pre-NIO 소켓을 사용하는 테스트 클래스입니다. 그러나 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
...