Socket Streams schliessen .. Exception gewollt?

diggaa1984

Top Contributor
hallo,

bei einer typischen client-server-geschichte muss man ja irgendwann auch mal die Streams der jeweiligen Sockets schliessen, wenn die Verbindung abgebaut wird. Client sowie Server warten ja in der Regel für die Dauer der Verbindung auf den Streams auf Eingaben und verarbeiten diese dann. Wenn die Verbindung abgebaut wird, dann werden die Streams geschlossen .. und PENG fliegt auf einer Seite der Verbindung ne IOException weil nicht mehr gelesen werden kann.

Ein Verbindungspartner ist ja immer der erste der schliesst, und der 2. guggt dann dumm aus der Wäsche 🙂
Ist das er normale Weg auch dann auf der 2. Seite alles weitere zu beenden, oder kann ich diese Exception irgendwie umgehen?

Mir will das nicht so recht in Sinn, dass ich auf die Exception warten muss.
 
was für eine Exception erhälst du denn bei genau welcher Aktion?
> weil nicht mehr gelesen werden kann
deutet ja auf irgendein Lesen hin, dazu fallen mir drei Dinge ein:
- wird nicht am Ende nur -1 gelesen wenn nix mehr da ist? deshalb: wobei genau die Exception?
- kann man nicht mit available()/ open() oder so abfragen ob noch was da ist/ ob Stream noch offen ist,
- wieso wird überhaupt noch gelesen, die beiden Partner sollten sich vorher auf ein Ende verständigen, dann muss auch keiner mehr lesen,
ansonsten sind Leseversuch + Gegenüber nicht mehr da zusammen durchaus eine besondere Situation, die eine Exception denkbar macht
 
gut war wohl ein wenig zu theoretisch 🙂

Java:
/**
	 * 
	 */
	@Override
	public void run() {
		String msg;
		try {
			while (keepRunning && (msg = iStream.readLine()) != null) {
				controller.receiveMessageFromServer(msg);
			}//while
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			socket.close();
		}//finally 
	}//run

mir geht es um solche Situationen .. wenn der Server hier als erster den Stream schliesst, dann fliegt beim Client die Exception .. Ich habe ebenfalls einen Thread, welcher Nachrichten zum Server schickt, quasi der 2. Stream des Sockets .. auch diesen muss ich ja korrekt beenden. Dein Vorschlag ist so eine Art Handshake beim Beenden zu machen, das klappt, wenn ich
Code:
keepRunning
auf false setze und der Client dann eine letzte Nachricht vom Server empfängt, dann wird die while-schleife ohne Expception verlassen, aber kann ich sowas universal bauen, ohne zu wissen welche Seite als erste den Abbruch veranlasst?

irgendwie hab ich dazu keine Beispiele im Netz gesehen und daher auch meine Vermutung, das es mit der Exception eher unschön wäre
 
Dein Vorschlag ist so eine Art Handshake beim Beenden zu machen, das klappt, wenn ich
Code:
keepRunning
auf false setze und der Client dann eine letzte Nachricht vom Server empfängt, dann wird die while-schleife ohne Expception verlassen, aber kann ich sowas universal bauen, ohne zu wissen welche Seite als erste den Abbruch veranlasst?

natürlich, sowas nennt sich Protokoll.
Als Beispiel: derjenige der die Verbindung schließen will sendet das Kommando "quit".
 
ja um nochmal meine drei Punkte Revue passieren zu lassen,

- es wird also beim fehlenden Socket nicht null zurückgegeben? na kann ja jeder selber testen, ich grad nicht, wie auch immer
- Socket hat eine Methode isClosed(), ist natürlich vielleicht zu aufwendig die bei jeder vakanten Stelle einzubauen,
und hilft vielleicht gar nicht wenn vor dem Lesen das Ende noch nicht festgestellt wurde,
oder gar das Ende erst zeitlich genau etwas später stattfindet
- das dritte und deine Frage: natürlich kann man ein Protokoll allgemein genug bauen, dass es hinkommt,
dann müssen die Lese- und Schreibstellen wirklich noch genauer überwacht werden,
das wird dann aber sehr individuell speziell so wie ich mir das vorstelle, vielleicht wenig interessant als allgemeine Lösung,

was macht die Verbindung denn bisher? sie tauscht Nachrichten/ Messages aus, da muss es eine für Ende geben,
auf beiden Seiten gibt es Kontrollobjekte die ankommende und ausgehende Nachrichten lesen und diesen Status erkennen,
könnte man als Wrapper um die Sockets herum bauen,
der Sender sendet 'Ende' und schließt dann mehr oder weniger automatisch 2 sec später die Verbindung,
vielleicht muss das vom Sender gar kein Code machen, sondern der Sender-Controller der die Ende-Nachricht erkannt hat,
der kümmert sich evtl. auch darum dass die Threads geschlossen werden,
beim Gegenüber erkennt genauso der Empfänger-Controller das Ende,

interessant sind nun die Lese- und Schreib-Codestellen, die können mehr oder weniger mit dem Controller verknüpft sein,
falls der Controller die entsprechenden Threads automatisch beendet ist vielleicht gar nix mehr zu tun,
ansonsten könnte man verpflichtet zu sein, die Code-Stellen wie folgt zu formulieren:

> while (keepRunning && socketController.isOpenConnection() && (msg = iStream.readLine()) != null) {
gegebenenfalls mit Synchronisation,

oder die Streams sind der Ansatz, kommunizieren intern mit dem Controller und liefern dann wirklich null zurück,
Möglichkeiten gibt es viele, man muss es nur bauen,

was als letztes Wort vielleicht ja nicht dein Wunsch ist, sondern ein schon vorhandener allgemein bekannter Ansatz 😉
 

Zurück
Oben