Wie kann eine TcpClient-Verbindung korrekt geschlossen oder zurückgesetzt werden? Wir haben Software, die mit Hardware kommuniziert, aber manchmal geht etwas schief und wir müssen nicht mehr mit ihr kommunizieren, bis wir die Software neu starten.
Ich habe versucht, TcpClient.Close () zu erzwingen und es sogar auf null zu setzen, aber das funktioniert nicht. Es funktioniert nur ein vollständiger Neustart der Software.
Vorschläge?
Ich kann das Schlüsselwort using nicht verwenden, da TpcClient nur an einem Ort definiert ist, aber 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 derzeit 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.
System.Net.Sockets.TcpClient
Rufen Sie mit .NET Standards aufDispose()
. Es gibt keineClose()
Methode.Da die akzeptierte Antwort veraltet ist und ich in den anderen Antworten dazu nichts sehe, erstelle ich eine neue. In .Net 2 und früheren Versionen mussten Sie den Stream manuell schließen, bevor Sie die Verbindung schließen konnten. Dieser Fehler wurde in allen späteren Versionen von
TcpClient
in C # behoben. Wie im Dokument der Close-Methode angegeben ,Close
schließt ein Aufruf der Methode sowohl die Verbindung als auch den StreamBEARBEITEN gemäß Microsoft Docs
Das Aufrufen dieser Methode führt schließlich zum Schließen des zugeordneten Sockets und schließt auch den zugeordneten NetworkStream, der zum Senden und Empfangen von Daten verwendet wird, wenn einer erstellt wurde.
quelle
networkStream.Close();
vor dem Aufruf auftcpClient.Close();
. Entweder ist das Beispiel veraltet oder Sie müssen den zugrunde liegenden Stream noch manuell schließen.Verwenden Sie das Wort :
using
. Eine gute Angewohnheit beim Programmieren.using (TcpClient tcpClient = new TcpClient()) { //operations tcpClient.Close(); }
quelle
async
Schlüsselwort hier ist, tut es das ;-). Es wäre sogar kompatibel mitBeginConnect()
undEndConnect()
, vorausgesetzt, Sie rufenEnd…
innerhalb desusing
Blocks an…Trotz aller entsprechenden
using
Anweisungen, AufrufenClose
, exponentieller Back-Off-Logik und Neuerstellung derTcpClient
habe ich immer noch Probleme festgestellt, bei denen die Anwendung die TCP-Verbindung ohne einen Neustart der Anwendung nicht wiederherstellen kann. Es scheitert immer wieder mit einemSystem.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host
.Es gibt jedoch eine Option,
LingerState
mit derTcpClient
das Problem möglicherweise behoben wurde (möglicherweise erst nach einigen Monaten, da mein eigenes Hardware-Setup nur so oft fehlschlägt!). 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 }) ...
quelle
Schließt eine Socket-Verbindung und ermöglicht die Wiederverwendung des Sockets:
tcpClient.Client.Disconnect(false);
quelle
TcpClient
dann eine Ausnahme für einen späteren ausgelöst.Connect
.Der richtige Weg, um die Steckdose zu schließen, damit Sie sie wieder öffnen können, ist:
tcpClient.Client.Disconnect(true);
Der Parameter Boolean gibt an, ob Sie den Socket wiederverwenden möchten:
quelle
Mit Ausnahme einiger interner Protokollierungen schließen Sie == Entsorgen.
Entsorgen Sie Aufrufe tcpClient.Client.Shutdown (SocketShutdown.Both), aber es frisst alle Fehler. Wenn Sie es direkt aufrufen, erhalten Sie möglicherweise nützliche Informationen zu Ausnahmen.
quelle
Haben Sie versucht, TcpClient.Dispose () explizit aufzurufen ?
Und sind Sie sicher, dass Sie über TcpClient.Close () und TcpClient.Dispose () ALLE Verbindungen verfügen ?
quelle
((IDisposable)client).Dispose()