Ist es möglich zu erkennen, ob ein Stream vom Client geschlossen wurde?

9

Eine kurze Zusammenfassung der Situation:

Ich habe einen Dienst, der Informationen empfängt und Antworten über Sockets sendet. Die Verbindungen sind ungesichert. Ich möchte einen anderen Dienst einrichten, der TLS für diese Verbindungen bereitstellen kann - dieser neue Dienst würde einen einzelnen Port bereitstellen und die Verbindungen basierend auf dem bereitgestellten Clientzertifikat verteilen. Ich möchte Stunnel nicht aus verschiedenen Gründen verwenden, da zum Beispiel pro Port ein Weiterleitungs-Port benötigt wird.

Die Lösung, die ich gerade implementieren möchte:

Im Wesentlichen versuche ich, einen SslStream (eingehend) mit einem NetworkStream zu verbinden (ausgehend - könnte ein Socket sein, aber ich lege es in einen NetworkStream, um den eingehenden zu entsprechen) und die Lese- / Schreiboperationen für die beiden verknüpft zu haben . Diese Verbindung würde den Fluss zwischen dem Client (über SSL / TLS) und dem Dienst (über eine ungesicherte Verbindung) bereitstellen.

Hier ist die Klasse, die ich entwickelt habe, um diese Streams zu verlinken:

%Vor%

Das Problem:

Wenn der Client mit dem Senden von Informationen fertig ist und SslStream entsorgt hat, hat der Server keinerlei Hinweise darauf, ob dies geschehen ist oder nicht. Diese StreamConnector-Klasse läuft glücklich in die Ewigkeit, ohne irgendwelche Fehler zu verursachen, und ich finde keinen Hinweis darauf, dass es aufhören sollte. (Es gibt natürlich die Tatsache, dass ich in ReadCallback jedes Mal die Länge 0 erhalte, aber ich muss in der Lage sein, lang laufende Verbindungen bereitzustellen, daher ist dies keine gute Art zu beurteilen.)

Ein weiteres mögliches Problem ist, dass ReadCallback aufgerufen wird, auch wenn keine Daten verfügbar sind. Ich bin mir nicht sicher, ob das anders wäre, wenn ich direkt einen Socket anstelle eines Streams verwenden würde, aber es scheint ineffizient zu sein, diesen Code immer wieder auszuführen.

Meine Fragen:

1) Gibt es eine Möglichkeit zu sagen, ob ein Stream von der Client-Seite geschlossen wurde?

2) Gibt es einen besseren Weg, um das zu tun, was ich versuche?

2a) Gibt es eine effizientere Möglichkeit, die asynchrone Lese- / Schreibschleife auszuführen?

BEARBEITEN: Danke, Robert. Stellt sich heraus, dass der Loop immer wieder angerufen wird, weil ich die Streams nicht geschlossen habe (weil ich nicht wusste, wie ich sagen konnte, wann die Streams geschlossen werden mussten). Ich schließe die vollständige Codelösung für den Fall ein, dass jemand anderes auf dieses Problem stößt:

%Vor%     
zimdanen 14.03.2012, 17:52
quelle

2 Antworten

3

Sie müssen versuchen, einen Socket zu lesen oder zu schreiben - oder irgendetwas, das darauf basiert -, um eine Trennung zu erkennen.

Wenn Sie versuchen zu schreiben, wird eine Exception ausgelöst / ein Fehler zurückgegeben (abhängig vom Paradigma Ihrer Sprache) oder möglicherweise nur 0 Bytes geschrieben. Das Lesen versucht entweder eine Ausnahme auszulösen / einen Fehler zurückzugeben (wiederum abhängig vom Paradigma Ihrer Sprache) oder return null .

Es ist erwähnenswert, dass, wenn Sie ein select-basiertes Servermodell verwenden, der getrennte Socket angezeigt wird - dh return select - als lesbar angezeigt wird, wenn die Verbindung getrennt wird, dann versuchen Sie, daraus zu lesen und den Fehler oder null .

    
Robert Allan Hennigan Leahy 14.03.2012, 18:38
quelle
0

Ich kann nicht anders, als zu denken, dass Ihr Client dem Server sagen sollte, wenn er mit irgendeiner Art von Nachricht fertig ist. Es ist immer am besten, wenn Sie darauf vorbereitet sind, dass ein Kabel abgeschnitten oder ein Stromausfall oder ein Stecker gezogen wird, aber im Allgemeinen möchten Sie eine Verbindung mit einer Art Endmarker beenden. Speichern Sie die Ausnahmen für echte Probleme, nicht für normale Gespräche.

    
RalphChapin 14.03.2012 21:17
quelle

Tags und Links