TCP Client mit StreamReader beenden

JJB

Cogito ergo brumm
Hallo zusammen !

Ich hab da ein Problem mit einer TCP Verbindung.
Und zwar mache ich Clientseitig über eine Socketverbindung eine Anfrage an einen Server.
In etwa so:

Code:
Socket itsSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);

// Starte Verbindung
IPEndPoint aEndpoint = new IPEndPoint(itsServerIP, itsPort);
itsSocket.Connect(aEndpoint);
NetworkStream itsNetworkStream = new NetworkStream(itsSocket);
StreamReader itsStreamReader = new StreamReader(itsNetworkStream);

// Lies Daten Zeilenweise ein, solange Stream verfügbar
while((itsStreamReader.Peek() >=0))
{
   String aString = itsStreamReader.ReadLine();
}

Der Client liesst nun, bis Serverseitig der Stream geschlossen wird.

Wenn ich nun aber will, dass die Verbindung schon vorher geschlossen wird, mache ich folgendes:

Code:
// Informiere Server über vorzeitiges Ende
SendKillSignal()

// Schließe Streams
if(itsStreamReader != null)
   itsStreamReader.Close();
if(itsNetworkStream != null)
   itsNetworkStream.Close();

// Schließe Socket
if(itsSocket.Connected)
   itsSocket.Close();

Damit wäre die Socketverbindung zwar geschlossen, aber der StreamReader erzeugt einen Fehler im Peek:

Code:
Exception: System.IO.IOException
Message: Von der Übertragungsverbindung können keine Daten gelesen werden.
Source: System
   at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
   at System.IO.StreamReader.ReadBuffer()
   at System.IO.StreamReader.Peek()
   at MyNameSpace.MyClass.ReceiveThread() in c:\home\MyNameSpace\MyClass.cs:line 488

Nested Exception

Exception: System.Net.Sockets.SocketException
Message: Eine bestehende Verbindung wurde softwaregesteuert
durch den Hostcomputer abgebrochen
Source: System
   at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
   at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)

Daher meine Frage, wie kann ich eine bestehende TCP Socket Verbindung (auf der noch ein StreamReader liesst) beenden, ohne eine Exception auszulösen ?
Ich muss den StreamReader doch irgendwie unterbrechen können, ohne dass er einen Fehler erzeugt.

Bin für jede Hilfe dankbar.

Hochachtungsvoll, JJB
 
Hallo.

Schonmal irgendwie versucht, den StreamReader zu beenden bevor der TcpClient geschlossen wird?

ohne eine Exception auszulösen

Es ist zwar schön, wenn keine Exceptions auftretten, dennoch solltest du sie behandeln. Gerade bei Netzwerkverbindungen kann es geschehen, dass die Verbindung aus irgendeinem Grund abbricht. Gewollt oder ungewollt.. Entsprechende Exceptions musst du da unbedingt behandeln, sonst geht dein Programm flöten.


Lg, Alex
 
Hallo,

siehe oben... ich dachte ich würde den StreamReader als erstes abschalten. Habe ich mich vertan ?

Exceptions behandle ich schon, doch sind sie eben unschön, sie unterbrechen meist den geregelten Ablauf und man weiß nie so recht, wo man nun steht, wenn man nicht um jeden winzigen kritischen Bereich Catch-Blöcke schreibt.
Wenn sich die Exceptions vermeiden lassen, will ich es so machen, wenn nicht, muß ich eben damit leben.

Ich schreibe es gerade so um, dass ich den Kommunikationspartner auffordere mich per Kommando zu schließen. So beenden sich die Partner gegenseitig. Das bringt mich aus der Warteschleife und der Reader wird nicht abgeschossen, sondern einfach durch den Partner geschlossen.

Wenn ich mich als Client abschalten möchte, schicke ich also an den Server eine Aufforderung zum Abbruch, der Server empfängt diese und beendet damit seinen Empfang und seine darauf folgende Antwort beendet den Empfang des Clients.
Wenn alles normal verläuft, klappt das ohne Exceptions. Diese erscheinen dann nicht mehr im geregelten Betrieb, sondern wirklich nur bei Ausnahmen und Fehlern. Und da gehören sie eigentlich hin.

Soweit denn...
Danke für reinschauen !
 
Hi

Mal eine Frage: Was passiert, wenn ich den Netzwerkstecker zieh? ;)
Dann tritt doch eine Exception auf und dein Programm winkt mit einen großen roten Dialog (oder es stützt direkt ab).

Bei Sockets kommt eine SocketExceptionen mit dem ErrorCode ConnectionReset. Wenn diese auch beim TCPClient kommt, solltest du diese auch behandeln (gilt übrigens immer für auftretende Exceptions). Nur wenn du Exceptions auch behandelst, kannst du bestimmt, was dein Programm im Fehlerfall machen soll, machst du das nicht, hat das Programm nur eine Wahl...
 
Ich benutze grundsätzlich Try-Catch-Blöcke doch eben für gewöhnlich zur Visualisierung von Fehlern und Ausnahmen.

Wenn ich eine Funktion starte und alles läuft wie geplant, sollte keine Exception auftauchen und den Anwender verunsichern. Es ist schließlich alles in Ordnung.
Nur wenn wirklich ein Fehler auftritt (z.B. Verbindungs- oder Datenverlust, Abbruch, spezielles Event, Anforderung durch Benutzer), sollte eine Exception auftreten. Diese wird abgefangen und angezeigt.
Sonst wäre eine Exception ja keine Exception (engl. = Ausnahme).
 
Zurück