2011-08-23 28 views
9

ライブラリ(.NET)で奇妙な動作を分離しようとするいくつかのテストを行っています。 C++でWinsock APIを使用してclosesocket()を呼び出すと、ウィンドウ側からFIN/ACKパケットが送信され、リモート側からACKパケットが返ってきます。これは私が優雅な終わりと呼ぶものです。しかし、C#でプログラミングするとき、私は優雅な終わりと呼ぶものを見ていません。.NETライブラリが閉じるときにRSTパケットを送信するのを防ぐ方法

C#ではソケットを開いて閉じて、ウィンドウにFINパケットを送信します。最初にSocket.Shutdown()を呼び出すときはのみです。しかし、関係なく、C#でSocket.Close()を呼び出すと、RSTパケットが送信され、接続が一時的に破棄されます。これは私が混乱させる理由は、TCPクローズプロセスがFIN/ACK - > ACKでなければならないからです(実際には両方の側からですが、今のところ私は "私"の側にしか関係しません)。すなわち、ミックス内にはRSTパケットが全く存在すべきではない。私が読んだところでは、明らかに、RSTパケットは、受信者が接続状態について不明確で、必要なときにのみ送信されます。

このRSTパケットは、.NETの計画シャットダウン時に送信され、winsock APIからの計画されたシャットダウンでは送信されないのはなぜですか? .NETからの正常なシャットダウン中にRSTパケットの送信を防止する方法はありますか?

どちらのコードパスでも、それぞれのclose()メソッドを呼び出す前に、ソケット上の利用可能なすべてのデータを読み込んでいます。

答えて

0

ちょうど最近、アプリケーションがPOP3をExchange Serverに話していたときに同様の問題が発生しました。 .NETプログラムが終了すると、プログラムは異常終了し、ExchangeはPOP3の会話を「中止」として処理してロールバックしました。

なぜなら、私はTCP RSTが「一方通行」のメッセージだと思います。返信を待つ必要はありません。

Thread.Sleep(5000); 

これは私が先に述べたPOP3の問題のために働いていた:それは、.NETが送信するものですので、(。またはおそらくそれが終了した後、任意のプログラム)一つの可能​​な解決策は、ソケットを閉じた後、プログラムを終了する前に少し待つことです;待機時間により接続が正常に終了し、Exchangeはセッションを中断しなくなりました。

+1

これは興味深いことです。私は睡眠を実装するときに何が起こるかを見なければならないでしょう。私はこれが起こっている完全な文脈のためにこれが実行可能であるとは思わないので、他に何が出現するのだろうか?私は動作を分離するスケルトンプログラムを作った。とにかくおかげさまで私はここで睡眠呼出しを使用することを考えなかったので、 –

3

Socket.Closeの.NETドキュメントを読むと、これは私が見つけたものです:

コネクション指向のプロトコルについては

、あなたがCloseメソッドを呼び出す前に シャットダウンを呼び出すことをお勧めします。これにより、すべてのデータ が接続されたソケットで閉じられた状態で送受信されます。 シャットダウンを呼び出さずにCloseを呼び出す必要がある場合は、 に、 DontLinger Socketオプションをfalseに設定し、ゼロ以外のタイムアウト時間 を指定することで、送信用にキューに入れられたデータが送信されるようにすることができます。このデータが送信されるか、または 指定されたタイムアウトが切れるまで、Closeはブロックされます。 DontLingerをfalseに設定し、 にゼロタイムアウト間隔を指定すると、Closeは接続を解放し、 は自動的に送信キューに入れられたデータを破棄します。

実際には意味があります。バッファ(OS 1)にまだデータがあり、接続を切断したり、プロセスを終了したりすると、接続はリセットされます(TCP仕様の詳細情報)。

RSTを送信するタイミングは、TCP Guideです。

RSTをトリガーする未設定または転送中のデータまたは送信/受信バッファがまだあると思います。

1

次のコードは、RSTパケットを防止する可能性があります。 FINパケットを送信してから60秒待つからです。

閉じるメソッドの説明はhereです。

関連する問題