it-swarm.com.de

Wie kann ich eine TcpClient-Verbindung richtig und vollständig schließen/zurücksetzen?

Was ist der richtige Weg, eine TcpClient-Verbindung zu schließen oder zurückzusetzen? Wir haben Software, die mit Hardware kommuniziert. Manchmal geht jedoch etwas

Ich habe versucht, TcpClient.Close () zu erzwingen und sogar auf null zu setzen, aber das funktioniert nicht .. __ Nur ein vollständiger Neustart der Software funktioniert.

Vorschläge?


Ich kann das Schlüsselwort using nicht verwenden, da TpcClient nur an einem Ort definiert ist und in der gesamten Bibliothek verwendet wird. (Und es gibt immer nur eine Verbindung)

Es ist eine Bibliothek, die die Kommunikation übernimmt. Die Software selbst kann die ResetConnection () - Methode der Controller-Klasse (die die Hardware darstellt) aufrufen.

Es sieht momentan so aus

if (tcpClient != null)
{
    tcpClient.Close();
    tcpClient = null;
}

Nach dem, was ich hier gelesen habe, sollte ich tcpClient.Dispose () anstelle von "= null" verwenden.

Ich werde es versuchen und sehen, ob es einen Unterschied macht.

64
TimothyP

Sie müssen den Stream schließen, bevor Sie die Verbindung schließen:

tcpClient.GetStream().Close();
tcpClient.Close();

Beim Schließen des Clients wird der Stream nicht geschlossen.

74

Da die akzeptierte Antwort veraltet ist und ich in den anderen Antworten dazu nichts sehe, erstelle ich eine neue. In .NET 2 und früher mussten Sie den Stream manuell schließen, bevor Sie die Verbindung beenden. Dieser Fehler wurde in allen späteren Versionen von TcpClient in C # behoben und wie im Dokument der Close-Methode angegeben Ein Aufruf der Methode Close schließt sowohl die Verbindung als auch den Stream

BEARBEITEN gemäß Microsoft Docs

Die Close-Methode markiert die Instanz als beseitigt und fordert die Der zugehörige Socket schließt die TCP - Verbindung. Basierend auf dem LingerState Eigenschaft, die TCP Verbindung kann nach dem .__ für einige Zeit geöffnet bleiben. Die Close-Methode wird aufgerufen, wenn noch Daten gesendet werden müssen. Es gibt kein Benachrichtigung, wenn die zugrunde liegende Verbindung abgeschlossen ist Schließen.

Der Aufruf dieser Methode führt letztendlich zum Schließen des zugeordneten Socket und zum Schließen des zugehörigen NetworkStream, der zum Senden und Empfangen von Daten verwendet wird, falls eine erstellt wurde.

21
John Demetriou

Verwenden Sie Word: using . Eine gute Angewohnheit beim Programmieren.

using (TcpClient tcpClient = new TcpClient())
{
     //operations
     tcpClient.Close();
}
20
Michał Ziober

Schließt eine Socket-Verbindung und ermöglicht die Wiederverwendung der Socket:

tcpClient.Client.Disconnect(false);
7
Justin Tanner

Der korrekte Weg, um den Sockel zu schließen, damit Sie ihn wieder öffnen können, ist:

tcpClient.Client.Disconnect(true);

Der boolesche Parameter gibt an, ob Sie den Socket wiederverwenden möchten:

 Disconnect method usage

4
Kevin Gigiano

Abgesehen von einigen internen Protokollierungen, Schließen == Dispose.

Dispose-Aufrufe tcpClient.Client.Shutdown (SocketShutdown.Both), aber es frisst alle Fehler. Wenn Sie es direkt aufrufen, erhalten Sie nützliche Ausnahmeinformationen.

4
jyoung

Obwohl alle using-Anweisungen vorhanden sind, der Aufruf von Close, eine exponentielle Back-Off-Logik und das Wiederherstellen der TcpClient-Funktion, sind immer noch Probleme aufgetreten, bei denen die Anwendung die Verbindung TCP ohne einen Neustart der Anwendung nicht wiederherstellen kann. Es schlägt immer mit einem System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote Host fehl.

Es gibt jedoch eine Option LingerState für die TcpClient, die das Problem möglicherweise gelöst hat (weiß möglicherweise nicht für einige Monate, da meine eigene Hardwareeinrichtung nur selten dazu ausfällt!). Siehe MSDN

// This discards any pending data and Winsock resets the connection.
LingerOption lingerOption = new LingerOption(true, 0);

using (var tcpClient = new TcpClient 
       {SendTimeout = 2000, ReceiveTimeout = 2000, LingerState = lingerOption })
   ...
2
Ian Mercer

Haben Sie versucht, TcpClient.Dispose () explizit aufzurufen?

Und sind Sie sicher, dass Sie TcpClient.Close () und TcpClient.Dispose () - ed ALL - Verbindungen haben?

0
chakrit