¿Cómo detectar un zócalo lateral remoto cerca?

¿Cómo se detecta si Socket#close() ha sido llamado en un socket en el lado remoto?

El método isConnected no ayudará, se devolverá true incluso si el lado remoto ha cerrado el socket. Prueba esto:

 public class MyServer { public static final int PORT = 12345; public static void main(String[] args) throws IOException, InterruptedException { ServerSocket ss = ServerSocketFactory.getDefault().createServerSocket(PORT); Socket s = ss.accept(); Thread.sleep(5000); ss.close(); s.close(); } } public class MyClient { public static void main(String[] args) throws IOException, InterruptedException { Socket s = SocketFactory.getDefault().createSocket("localhost", MyServer.PORT); System.out.println(" connected: " + s.isConnected()); Thread.sleep(10000); System.out.println(" connected: " + s.isConnected()); } } 

Inicie el servidor, inicie el cliente. Verá que imprime “connected: true” dos veces, aunque el socket esté cerrado la segunda vez.

La única manera de descubrirlo realmente es leyendo (obtendrás -1 como valor de retorno) o escribiendo (se IOException una IOException (tubería rota)) en los flujos de entrada / salida asociados.

Como las respuestas se desviaron, decidí probar esto y publicar el resultado, incluido el ejemplo de la prueba.

El servidor aquí solo escribe datos en un cliente y no espera ninguna entrada.

El servidor:

 ServerSocket serverSocket = new ServerSocket(4444); Socket clientSocket = serverSocket.accept(); PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); while (true) { out.println("output"); if (out.checkError()) System.out.println("ERROR writing data to socket !!!"); System.out.println(clientSocket.isConnected()); System.out.println(clientSocket.getInputStream().read()); // thread sleep ... // break condition , close sockets and the like ... } 
  • clientSocket.isConnected () devuelve siempre verdadero una vez que el cliente se conecta (¡e incluso después de la desconexión) raro!
  • getInputStream (). read ()
    • hace que el hilo espere la entrada siempre que el cliente esté conectado y por lo tanto hace que su progtwig no haga nada, excepto si obtiene alguna entrada
    • devuelve -1 si el cliente se desconectó
  • out.checkError () es verdadero tan pronto como el cliente se desconecta, así que lo recomiendo

También puede verificar el error de flujo de salida del socket mientras escribe en el socket del cliente.

 out.println(output); if(out.checkError()) { throw new Exception("Error transmitting data."); } 

El método Socket.Available arrojará inmediatamente una SocketException si el sistema remoto ha desconectado / cerrado la conexión.