バックグラウンド:
TCPを介して接続する別々のマシン上の複数のクライアントを備えた1台のマシンでTCPサーバーを実行しており、Wiresharkを使用して、サーバーアプリケーション内から、およびSystem.NetのSystem.Diagnosticstracelistenerを介してログを記録してネットワークトラフィックを監視しています。 。冗長モードのソケット。
問題:
予期しない切断が発生したためにログを調べるように求められましたが、非常に奇妙な動作が見られます。サーバーアプリケーションログとSystem.Diagnostic出力ログによると、サーバーは開始/終了送信を使用して4バイトのパケットをクライアントに送信しています。BeginSendが完了し、EndSendも4バイトのパケットを正常に送信したことを示して完了します。
ただし、Wiresharkのログを見ると、そのパケットは表示されません。サーバーマシンでWiresharkを実行しているので、パケットがサーバーとトレースログに表示される理由はありませんが、同じマシンのWiresharkログには表示されません。
また、パケット送信が成功したと思われる直後(約30秒後)に予期しない切断が発生します。これは、サーバーのEndReceiveメソッドのSocketExceptionが原因で発生します。しかし、サーバーからの送信が試行されるまでの間に、サーバーはクライアントから受信したパケットを確認しているので、接続がまだアクティブであることがわかります。
誰かが同様の経験をしたことがありますか、またはこれを引き起こしている可能性のあるバグや何かを知っていますか?
これがソケットレベルで発生しているとは考えたくありません。TCPは、パケットがネットワークに到達しなかったときに送信されると言っています。つまり、信頼できるトランスポートとしてTCPに依存することはできません(もちろん、 TCPの要点です)。
ログサンプル
私のサーバーアプリケーションから:
2011-09-07 10:41:38,812 Attempting to send Packet (BeginSend - 4 bytes)
2011-09-07 10:41:38,812 Sent Packet (EndSend - 4 bytes)
System.Diagnosticsトレースログから:
System.Net.Sockets Verbose: 0 : [4376] Socket#19699911::BeginSend()
DateTime=2011-09-07T17:41:38.8125000Z
System.Net.Sockets Verbose: 0 : [0980] Data from Socket#19699911::PostCompletion
DateTime=2011-09-07T17:41:38.8125000Z
System.Net.Sockets Verbose: 0 : [0980] 00000000 : 02 04 00 00 : ....
DateTime=2011-09-07T17:41:38.8125000Z
System.Net.Sockets Verbose: 0 : [4376] Socket#19699911::EndSend(OverlappedAsyncResult#44209720)
DateTime=2011-09-07T17:41:38.8125000Z
System.Net.Sockets Verbose: 0 : [4376] Exiting Socket#19699911::EndSend() -> 4#4
DateTime=2011-09-07T17:41:38.8125000Z
System.Net.Sockets Verbose: 0 : [4376] Exiting Socket#19699911::BeginSend() -> OverlappedAsyncResult#44209720
DateTime=2011-09-07T17:41:38.8125000Z
Wiresharkのログも貼り付けますが、クライアントからのパケットとサーバーからの対応する確認応答を除いて、基本的にその時点でそのデバイスのインターフェイスに登録されているものはありません。
編集: 要求に応じて、ここに送信のコードがあります(スペースなどの理由で短縮されています)。非常に単純で、問題が発生する可能性のあるものの邪魔になることはあまりありません。
私のBeginSendメソッドでは:
socket.BeginSend(data, 0, data.Length, SocketFlags.None, EndSend, state);
私のEndSendメソッドでは:
bytesSent = socket.EndSend(ar);
注:彼らが言うように、これは私の最初のロデオではありません...私は過去15年間、TCPソケットを使用してサーバーとクライアントを作成してきましたが、これまで経験したことはありません。
また、私が使用している.NETのバージョンは4.0です...それが関連性がある場合。
ヘルプ!