TcpClient接続を閉じるまたはリセットする正しい方法は何ですか?ハードウェアと通信するソフトウェアがありますが、時々何かがおかしくなり、ソフトウェアを再起動するまで通信できなくなります。
TcpClient.Close()を強制し、nullに設定しようとしましたが、うまくいきません。ソフトウェアの完全な再起動のみが機能します。
提案?
TpcClientは1つの場所でのみ定義されていますが、ライブラリ全体で使用されているため、usingキーワードは使用できません。 (また、常に1つの接続のみが存在します)
これは、通信を処理するライブラリです。ソフトウェア自体は、コントローラクラス(ハードウェアを表す)のResetConnection()メソッドを呼び出すことができます。
現在のように見えます
if (tcpClient != null)
{
tcpClient.Close();
tcpClient = null;
}
ここで読んだことから、「= null」の代わりにtcpClient.Dispose()を使用する必要があります。
それを試して、それが違いを生むかどうかを確認します。
接続を閉じる前にストリームを閉じる必要があります。
tcpClient.GetStream().Close();
tcpClient.Close();
クライアントを閉じても、ストリームは閉じられません。
受け入れられた答えは時代遅れであり、これに関する他の答えには何も見られないので、私は新しいものを作成しています。 .Net 2以前では、接続を閉じる前に手動でストリームを閉じる必要がありました。このバグは、C#のTcpClient
の以降のすべてのバージョンで修正されており、 Closeメソッド のドキュメントに記載されているように、メソッドClose
の呼び出しは接続とストリーム
Microsoft Docsに従って編集
Closeメソッドは、インスタンスを破棄済みとしてマークし、関連付けられたSocketがTCP接続を閉じることを要求します。LingerStateプロパティに基づいて、TCP接続は開いたままになることがありますCloseメソッドが呼び出された後、データの送信がまだ残っている場合、基礎となる接続のクローズが完了したときに通知は提供されません。
このメソッドを呼び出すと、最終的には関連付けられたSocketが閉じられ、データが作成された場合はデータの送受信に使用されるNetworkStreamも閉じられます。
Wordを使用: using
プログラミングの良い習慣。
using (TcpClient tcpClient = new TcpClient())
{
//operations
tcpClient.Close();
}
ソケット接続を閉じて、ソケットの再利用を許可します。
tcpClient.Client.Disconnect(false);
一部の内部ロギングを除き、Close == Dispose。
破棄はtcpClient.Client.Shutdown(SocketShutdown.Both)を呼び出しますが、エラーはすべて処理されます。直接呼び出すと、役に立つ例外情報を取得できる場合があります。
適切なusing
ステートメントがすべてあるにもかかわらず、Close
を呼び出し、指数関数的なバックオフロジックを使用してTcpClient
を再作成しますが、アプリケーションが=を回復できない問題がまだあります。 TCPアプリケーションを再起動せずに接続します。System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote Host
。
しかし、LingerState
にオプションTcpClient
があり、問題を解決した可能性があります(私自身のハードウェアのセットアップが失敗することが多いため、数か月間はわからないかもしれません!)。 [〜#〜] 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 })
...
TcpClient.Dispose() を明示的に呼び出してみましたか?
TcpClient.Close()およびTcpClient.Dispose()-ed[〜#〜] all [〜#〜]接続があることを確認してください?