2009-01-27 3 views
12

Hey alle. Ich habe einen Server in Java mit den ServerSocket und Socket-Klassen geschrieben.Wie behandeln Sie Socket Disconnecting in Java?

Ich möchte in der Lage sein, Verbindungsabbrüche zu erkennen und zu behandeln, und schließe dann bei Bedarf einen neuen Client erneut an.

Was ist die richtige Prozedur, um Client-Verbindungsabbrüche zu erkennen, den Socket zu schließen und dann neue Clients zu akzeptieren?

Antwort

12

Vermutlich lesen Sie aus dem Socket, möglicherweise mit einem Wrapper über den Eingabestream, z. B. einem BufferedReader. In diesem Fall können Sie das Ende des Streams erkennen, wenn die entsprechende Leseoperation -1 (für raw read() - Aufrufe) oder null (für readLine() - Aufrufe zurückgibt).

Bestimmte Vorgänge verursachen eine SocketException, wenn sie an einem geschlossenen Socket ausgeführt wird, mit dem Sie ebenfalls angemessen umgehen müssen.

+0

Wo 'geschlossene Socket' bedeutet, dass * Sie * den Socket geschlossen haben, nicht, dass der Peer die Verbindung geschlossen hat. Alle anderen readXXX() -Methoden, die nicht die genannten sind, werfen EOFException ab, wenn EOS auftritt. – EJP

4

Die einzige sichere Möglichkeit, das andere Ende zu erkennen, ist das periodische Senden von Heartbeats und das Ausbleiben des Timeout aufgrund eines fehlenden Heartbeats.

+0

Oder Sie könnten nur die Zeitüberschreitung – Pyrolistical

+2

Ich habe einen Thread, der jede Verbindung untersucht, um zu sehen, wie lange es seit dem letzten Paket gelesen wurde. (Herzschlag oder anders) Es ist zu lange, ich schließe die Verbindung. –

+0

@PeterLawrey, Senden von Herzschlag ist eine der besten Lösung die meisten der Telekommunikation verwendet Heartbeat, um auf die Trennung zu reagieren. –

0

Ist es nur ich, oder hat niemand bemerkt, dass das JavaDoc eine Methode unter ServerSocket api angibt, die uns ermöglicht, einen Booleschen Wert basierend auf dem geschlossenen Zustand des Servers zu erhalten?

Sie alle paar Sekunden nur Schleife kann den Zustand der es zu überprüfen:

if(!serverSocket.isClosed()){ 
    // whatever you want to do if the serverSocket is connected 
}else{ 
    // treat a disconnected serverSocket 
} 

EDIT: Sie Ihre Frage zu lesen wieder, so scheint es, dass Sie den Server erfordern nur ständig nach Verbindungen zu suchen, um zu und wenn der Kunde trennt, sollte es in der Lage sein, erneut zu erkennen, wenn der Client versucht, die Verbindung wiederherzustellen. sollte das nicht nur Ihre Lösung sein?

Wenn ein Server eine Verbindung herstellt, sollte er diese an ein Worker-Thread-Objekt übergeben und zum asynchronen Betrieb starten. Dann kann der Server einfach wieder auf neue Verbindungen warten. Wenn der Client die Verbindung trennt, sollte der gestartete Thread abstürzen und bei der erneuten Verbindung wird ein neuer Thread erneut gestartet, um die neue Verbindung zu verarbeiten.

Jenkov bietet ein großartiges Beispiel für diese Implementierung.

+0

'isClosed()' sagt Ihnen nicht, ob der Peer die Verbindung getrennt hat. Es sagt dir, ob * du * deinen Sockel * geschlossen hast. – EJP