web-dev-qa-db-fra.com

Comment détecter une fermeture de socket côté distant?

Comment détecter si Socket#close() a été appelé sur une prise du côté distant?

82
Kevin Wong

La méthode isConnected ne vous aidera pas, elle retournera true même si le côté distant a fermé le socket. Essaye ça:

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());
    }
}

Démarrez le serveur, démarrez le client. Vous verrez qu'il est imprimé "connected: true" deux fois, même si le socket est fermé une deuxième fois.

La seule façon de vraiment le savoir est de lire (vous obtiendrez -1 comme valeur de retour) ou d'écrire (un IOException (tuyau cassé sera jeté) sur les flux d'entrée/de sortie associés.

62
WMR

Comme les réponses diffèrent, j'ai décidé de tester cela et d'afficher le résultat - y compris l'exemple de test.

Ici, le serveur écrit simplement des données sur un client et n'attend aucune entrée.

Le serveur:

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 () renvoie toujours la valeur true une fois le client connecté (et même après la déconnexion) bizarre !!
  • getInputStream (). read ()
    • fait en sorte que le thread attende une entrée tant que le client est connecté et empêche donc votre programme de faire quoi que ce soit - sauf si vous obtenez une entrée
    • renvoie -1 si le client s'est déconnecté
  • out.checkError () est vrai dès que le client est déconnecté, je vous le recommande donc
26
Thorsten Niehues

Vous pouvez également rechercher une erreur de flux de sortie du socket lors de l'écriture sur le socket client.

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