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.
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.
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.
Verwenden Sie Word: using
. Eine gute Angewohnheit beim Programmieren.
using (TcpClient tcpClient = new TcpClient())
{
//operations
tcpClient.Close();
}
Schließt eine Socket-Verbindung und ermöglicht die Wiederverwendung der Socket:
tcpClient.Client.Disconnect(false);
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.
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 })
...
Haben Sie versucht, TcpClient.Dispose () explizit aufzurufen?
Und sind Sie sicher, dass Sie TcpClient.Close () und TcpClient.Dispose () - ed ALL - Verbindungen haben?