it-swarm.com.de

Wie erkennt man, dass eine Remote-Side-Buchse geschlossen ist?

Wie erkennen Sie, ob Socket#close() an einem Socket auf der Remote-Seite aufgerufen wurde?

82
Kevin Wong

Die Methode isConnected hilft nicht weiter, sie gibt true zurück, auch wenn die Remote-Seite den Socket geschlossen hat. Versuche dies:

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

Starten Sie den Server und den Client. Sie werden sehen, dass es zweimal "connected: true" ausgibt, obwohl der Socket das zweite Mal geschlossen wird.

Die einzige Möglichkeit, dies herauszufinden, ist das Lesen (Sie erhalten -1 als Rückgabewert) oder das Schreiben (es wird eine IOException (unterbrochene Pipe) auf die zugehörigen Input/OutputStreams geworfen).

62
WMR

Da die Antworten abweichen, habe ich mich entschlossen, dies zu testen und das Ergebnis zu posten - einschließlich des Testbeispiels.

Der Server schreibt hier nur Daten auf einen Client und erwartet keine Eingabe.

Der Server:

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 () gibt immer true zurück, wenn der Client eine Verbindung herstellt (und auch nach dem Trennen), komisch !!
  • getInputStream (). read ()
    • lässt den Thread auf Eingaben warten, solange der Client verbunden ist, und lässt Ihr Programm daher nichts tun - es sei denn, Sie erhalten Eingaben
    • gibt -1 zurück, wenn der Client die Verbindung getrennt hat
  • out.checkError () ist true, sobald die Verbindung zum Client getrennt wird, daher empfehle ich dies
26

Sie können auch beim Schreiben auf den Client-Socket auf Socket-Ausgabestreamfehler prüfen.

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