Wahrnehmen, dass ServerSocket geschlossen wurde

max5432

Aktives Mitglied
Hallo

Wie kann ich auf der Client-Seite merken, dass der ServerSocket geschlossen wurde? Kann ich irgendwie den Socket (Client-Socket) testen (isConnected / isBound / usw.), um dies festzustellen? Ich habe mit isConnected, isBound usw. versucht, jedoch ohne Erfolg.

Hinweis:
Verbindung wird aufgebaut und die Streams geholt. Jedoch wird das Schreiben und das Lesen nur auf Aufforderung durchgeführt. So bin ich auf der Client-Seite nicht am Warten

Java:
String input = bReader.readLine();

oder so was ähnliches.

Hat jemand einen guten Tipp? Ich komme nicht weiter, und es ist recht spät (oder früh, wie man es nimmt ;( )

Danke.
 

Empire Phoenix

Top Contributor
Du könntest erstens die read ineinen eigenen Thread verlagern dann hängt nicht das Programm falls keine daten zum lesen verfügbar sind., Zudem ein einfacher test ob ne Connection noch aktiv ist, schick einen code den der server antwortet (aka ping,pong)
 

max5432

Aktives Mitglied
Danke für die Antwort.

Ein "ping" wäre sicher möglich, finde ich aber etwas unschön.

Und wegen Auslagerung von read-Aktionen in einen eigenen Thread ...

Ich habe eine GUI auf der Client-Seite, die allerdings die ganze Kommunikation mit dem Server über eine Proxy-Komponente abwickelt. Die Nachrichten,die zu übertragen sind, sind kurz und verursachen an sich keine Verzögerung in der GUI-Anzeige. Wenn ich eine Aktion durchführen möchte, wird entsprechende Methode auf der Proxy-Komponente aufgerufen, die ihrerseits eine passende Nachricht sendet und direkt danach die Antwort liest. Danach steht die Socketverbindung leer, bis die nächste Aktion wierder veranlasst wird. Ich sehe den gewinn durch einen separaten read-Thread nicht ganz: sicher könnte ich die GUI problemlos auch dann anzeigen, wenn sich das Lesen "aufhängen" sollte, jedoch handelt es sich um eine synchrone Kommunikation, bei der ich auf die Antwort des Servers angewiesen bin. Also, wenn die Antwort nicht kommt, ist das schon einmal nicht gut. Oder, hast du es anders gemeint?

Ich möchte verhindern, dass der Client eine Aktion veranlasst und erst beim Senden der Anfrage erfährt, dass die Verbindung nicht mehr steht (wie dies jetzt der Fall ist): die unnötige Eingabe von Daten könnte man sich sparen. Der Client verabschiedet sich "anständig" beim Server, wenn er beendet wird. Der Server sollte dies auch tun, damit ich den Client-Benutzer informieren kann, dass die Verbindung nicht mehr da ist. Er kann ein "Tschüss" schon senden, nun ist auf der Client-Seite niemand, der es entgegennimmt.

Ich habe versucht, mit einem "WatchDog"-Thread, der den InputStream des Sockets erhält und den Abschied des Servers "hören" kann. Nun hat das aber nicht so gut geklappt, wie ich wollte. Sobald ein Thread den Inhalt des Streams gelesen hat, bleibt der andere "hängen". Und, dem WatchDog zu sagen, dass die Proxy-Komponenten an sich auf die Antwort waretet und er da nicht "rein funken" soll, ist mir nich so richtig gelungen. Habe zwar mit dem PushbackInputStream versucht, die Nachricht, die nicht für WatchDog war, in den InputStream zurück zu schreiben (unread-Methode), aber bin auch nicht viel weiter gekommen. Ab und zu hat es schön funktioniert, aber nur ab und zu.
 

MQue

Top Contributor
Also ich würde

Socket#setSoTimeout(X) setzen und dann mit Socket#isConnected() vor dem Senden abfragen, ob dieser noch verbunden ist, das müsste funktionieren.
 

max5432

Aktives Mitglied
Also ich würde

Socket#setSoTimeout(X) setzen und dann mit Socket#isConnected() vor dem Senden abfragen, ob dieser noch verbunden ist, das müsste funktionieren.

Habe es versucht:

Proxy:

Java:
/* Socket erzeugen */
clientSocket = new Socket(hostIp, servicePort);

/* Timeout setzen */
clientSocket.setSoTimeout(3000); 

// ...

/* Methode zum Prüfen, ob Socket immer noch verbunden ist */
public boolean isConnected(){
    return clientSocket.isConnected(); 
}

In der GUI frage ich jetzt ab (bevor die Eingabe von Daten in einem Dialog vorgenommen wird), ob die Verbindung steht:

Java:
// Methode 'actionPerformed' ... 

boolean connected = proxy.isConntected(); 

if (connected) {
    // Daten eingeben 

    // Passende Methode auf der Proxy-Komponenten aufrufen und auf die Antwort warten 
 

}
else {
    // Passende Meldung mit JOptionPane anzeigen ...

}

Die Verbindung wird hergestellt und kurz danach wieder beendet vom Server. Ich warte sicherheitshalber länger als 3 Sekunden!!! bevor ich die Aktion starte, die proxy.isConnected aufruft. Leifer bekomme ich auch hier "true", obwohl der Server schon längst nicht mehr 'online' ist.

Oder, habe ich was falsch verstanden?

Und, der Server ist sicher nicht mehr online: Wenn ich einen neuen Client starte und Verbindung herstellen versuche, klappt es nicht mehr.
 
Zuletzt bearbeitet:

MQue

Top Contributor
Probiers mal so:

Java:
private boolean isConnected() {
        if(socket != null && inputStream != null && outputStream != null)
            return socket.isConnected();
        return false;
        }
 
T

tuxedo

Gast
isCOnnected() prüft intern nur ein Flag ab. Soweit ich das gesehen habe wird das nicht durch einen "verbindungsverlust" rückgesetzt, sondern nur, wenn du in den Fehler reinläufst.

Die einzig wahre Möglichkeit rauszufinden ob die Verbindung noch funktioniert ist ein PingPong auf Protokoll-Eben zu betreiben.

Ansonsten bleibt dir nur noch
Code:
setKeepAlive()
auf dem Socket zu setzen und zu hoffen, dass der Verbindungsabbruch auf Zeitnah erkannt wird (was nicht garantiert wird).

Siehe zu dem Thema auch: socket : Java Glossary

Gruß
Alex
 

max5432

Aktives Mitglied
Probiers mal so:

Java:
private boolean isConnected() {
        if(socket != null && inputStream != null && outputStream != null)
            return socket.isConnected();
        return false;
        }

Danke.

Habe es getestet: leider funktioniert dies auch nicht.

Nun, ich habe es jetzt wie folgt "gelöst":
Bevor ich eine Aktion starte, sende ich ein "ping" zum Server, um zu erfahren, ob er noch online ist. So kann ich zumindest die nutzlose Eingabe von Daten verhindern, wenn die Verbindung nicht mehr steht.
 
T

tuxedo

Gast
Nun, ich habe es jetzt wie folgt "gelöst":
Bevor ich eine Aktion starte, sende ich ein "ping" zum Server, um zu erfahren, ob er noch online ist. So kann ich zumindest die nutzlose Eingabe von Daten verhindern, wenn die Verbindung nicht mehr steht.

Wieso so "kompliziert"?

Wenn du eine Aktion startest, dann a) klappt das oder b) kommt eine Exception. Das reicht doch?

Wenn du jetzt vorher noch ein Ping Paket schickst, dann macht das das gleiche in grün: Es wird geschaut ob's klappt oder ob eine Exception kommt.

PingPong macht eigentlich nur dann Sinn, wenn die Verbindung "herum idle't" und du möglichst zeitnah mitkriegen willst ob die Verbindung tot ist. Wenn du eh immer wieder Daten sendest, dann brauchst du kein PingPong.

- Alex
 

max5432

Aktives Mitglied
Wieso so "kompliziert"?

Wenn du eine Aktion startest, dann a) klappt das oder b) kommt eine Exception. Das reicht doch?

Wenn du jetzt vorher noch ein Ping Paket schickst, dann macht das das gleiche in grün: Es wird geschaut ob's klappt oder ob eine Exception kommt.

PingPong macht eigentlich nur dann Sinn, wenn die Verbindung "herum idle't" und du möglichst zeitnah mitkriegen willst ob die Verbindung tot ist. Wenn du eh immer wieder Daten sendest, dann brauchst du kein PingPong.

- Alex


Ich habe einen Fall, wo der Benutzer relativ viel Daten in einem Dialog eingeben muss. Bevor er dies macht, möchte ich sicher sein, dass die Verbindung steht, damit er die Eingabe nicht umsonst tätigt (falls z. B. der Server heruntergefahren wurde). Also, er merkt, dass die Verbindung nicht steht und stellt zuerst die Verbindung her: wenn es klappt, macht er weiter, sonnst gibt er auf. Eine andere Variante wäre sicher die eingegeben Daten zu retten und die nach dem neuen Verbindungsaufbau wieder zu senden. Dies scheint mir aber komplizierter zu sein. Ausserdem (wie schon geschrieben) kann es sein, dass der Server gar nicht läuft (heruntergefahren). In diesem Fall wird sich die Freude des Benutzer über die umsonst eingegebenen Daten zeimlich "im Rahmen" halten. :bahnhof:
 
T

tuxedo

Gast
Aaaalso. Du wirst ja erst den Dialog mit "weiter" oder "okay" abschließen bevor du anfängst zu senden.

Ergo hast du ein Sammelsurium von Variablen/Daten die gesendet werden müssen.

Die gehen mit dem Senden ja nicht gleich verloren. Das senden umschließt du mit einem Try/Catch und probierst im Catch den die Verbindung wiederherzustellen und die Daten (die Variablen sind ja noch da) nochmal zu senden.

Den Ping voran schieben macht die Sache nicht anders. Das ist doch das gleiche in grün?! Was ist wenn der ping funktioniert und dann das senden der Daten fehl schlägt? Auf den Ping kannst du dich nicht allein verlassen.

- Alex
 

max5432

Aktives Mitglied
Was ist wenn der ping funktioniert und dann das senden der Daten fehl schlägt? Auf den Ping kannst du dich nicht allein verlassen.

Das stimmt. Eine gewisse Unsicherheit bleibt halt immer.

Ich habe auf die automatische Weiderherstellung der Verbindung zur Zeit verzichtet. Jedoch finde ich diene Überlegung richtig und werde versuchen, meinen Code entsprechend anzupassen.

Gruss,

max5432
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
D Socket Socket absichtlich so schließen, dass Gegenseite java.net.SocketException: Connection reset wirft Netzwerkprogrammierung 4
E Custom E Mail Adresse mithilfe Serversocket oder ähnliches Netzwerkprogrammierung 21
Tobero Java serversocket nicht nur zuganglich für localhost Netzwerkprogrammierung 6
D ServerSocket - Socket Verbindungsart Netzwerkprogrammierung 3
J 1 Socket - 2 Serversocket Netzwerkprogrammierung 4
J Client - Serversocket Netzwerkprogrammierung 1
Seikuassi Socket ServerSocket mehrmals erzeugen Netzwerkprogrammierung 1
cezary Socket ServerSocket starten über GUIIm unterstehenden Code versuche Netzwerkprogrammierung 6
J ServerSocket sauber beenden Netzwerkprogrammierung 3
H ServerSocket.accept() unterbrechen Netzwerkprogrammierung 3
TheJavaKid ServerSocket beendet mit PuTTy Netzwerkprogrammierung 9
T ServerSocket.accept Rückgabetyp casten Netzwerkprogrammierung 3
P Socket Daten senden mit ServerSocket? Netzwerkprogrammierung 2
4 Socket Kann kein ServerSocket erstellen Netzwerkprogrammierung 4
D Socket ServerSocket Push Netzwerkprogrammierung 5
G ServerSocket.accept() überschreibt IP-Adresse Netzwerkprogrammierung 4
C serversocket.accept() klappt nicht Netzwerkprogrammierung 10
Tobse HTTP ServerSocket HTTP Netzwerkprogrammierung 4
X FAQ Frage - Netzwerkgrundlagen - ServerSocket und Socket Netzwerkprogrammierung 4
T ServerSocket bleibt beim lesen von Input hängen Netzwerkprogrammierung 2
M ServerSocket.accept() abbrechen Netzwerkprogrammierung 8
Schandro Herausfinden ob hinter einem Port bereits ein ServerSocket steckt Netzwerkprogrammierung 2
2 Class mit ServerSocket erbt von Thread? Netzwerkprogrammierung 3
T Java Socket und ServerSocket über Internet-IP? Netzwerkprogrammierung 9
dayaftereh serverSocket.accept(); Wecken Netzwerkprogrammierung 2
G Frage zu Serversocket-Beispiel aus der FAQ Netzwerkprogrammierung 17
D Komisches Fenster bei Serversocket Netzwerkprogrammierung 2
M Kommunikation zwischen ServerSocket und Socket Netzwerkprogrammierung 2
F ServerSocket im internet zugänglich machen Netzwerkprogrammierung 15
H ServerSocket -> Zugriff nur von localhost Netzwerkprogrammierung 6
P Serversocket schmeißt immmer EOFEXCEPTION Netzwerkprogrammierung 2
A serversocket soll anfrage vom handy entgegennehmen Netzwerkprogrammierung 4
P Problem mit Socket und ServerSocket Netzwerkprogrammierung 2
S ServerSocket merkt nicht, wenn keiner mehr da ist Netzwerkprogrammierung 8
J ServerSocket vs. DatagramSocket Netzwerkprogrammierung 2
A ServerSocket prinzipielle Frage Netzwerkprogrammierung 5
D Problem ServerSocket global Netzwerkprogrammierung 3
J ServerSocket schließen / öffnen im Programmverlauf Netzwerkprogrammierung 4
G einfache Frage zu ServerSocket ... Netzwerkprogrammierung 5

Ähnliche Java Themen


Oben