3

私は このようにStreamWriterインスタンス化されたものを使用していますTcpstream

streamWriter = new StreamWriter(tcpClient.GetStream());    

例外に関して、次の呼び出しの動作について混乱しています。次の2つの関数は、発生することが予想されます。IOException驚くべきことに、接続IOException先のサーバーが切断されたtcpClientため、基盤となるTCPクライアント接続が切断されたときに発生しません。これらの2つの行は、例外を発生させずに実行されます。なんで ?

streamWriter.WriteLine(strBuffer);
streamWriter.Flush();

編集:この特定の投稿は、専門家からのここでの返信に加えて、理由を理解するのにも役立ちました。 http://social.msdn.microsoft.com/Forums/sk/netfxnetcom/thread/b177a935-7430-4812-9555-f747748df1af 本質的に、StreamWriterのWriteLineが呼び出されると、NetworkStream.Writeが呼び出されます。バッファがいっぱいである場合を除いて、バッファに移動し、ブロックせずに戻ります。OSによって維持されている内部バッファには、未送信のデータが含まれています。このデータは、指定された回数の試行が失敗するまで、OSが送信を試み続けます。WriteLineはIOExceptionをスローしますが、必ずしも毎回ではありません。

4

2 に答える 2

2

この問題はとは関係ありません。StreamWriterそれはの動作に関するものだけですNetworkStream

NetworkStream.Flush()ノーオペレーションです。特に、フラッシュの前に送信されたすべてのバイトを受信者が確認するまで、ブロックされません。

FlushメソッドはStream.Flushメソッドを実装します。ただし、NetworkStreamはバッファリングされないため、ネットワークストリームには影響しません。Flushメソッドを呼び出しても、例外はスローされません。

NetworkStream.Flushメソッド(MSDN)から)

ある時点で例外が発生しますが、それはかなり後になる可能性があります。基本的NetworkStreamに、TCP接続がすでに切断されていることをOSもOSも認識していないため、例外は発生しません。

于 2012-12-13T11:21:32.017 に答える
1

これはTCPのコアな側面であり、ネットワークを介して別のマシンにデータを確実に転送することを約束するプロトコルです。データが実際に他のマシンに到達することを確認するのは、オペレーティングシステムの仕事です。データを書き込んだ後もずっと、何度もデータを取得しようとします。確認応答がない場合は、必要に応じてIPパケットを再送信します。これは、マシンを切断した場合に当てはまります。何度も試してみても諦めません。それが諦めるまでに1分もかかることがあります。

この契約では、接続がユーザー側で信頼できると見なされることが暗黙的に示されています。書き込んだものはすべて、カーネルメモリプールにあるバッファに格納されます。このバッファは、プログラムのスループットを大幅に向上させ、プログラムと可変伝送速度の間の余裕を取ります。バッファに入ると、データが実際に送信されることを保証するのはオペレーティングシステムの義務です。

あなたはこれがどこに行くのかを見ることができます、あなたは後でまで切断から例外を受け取りません。バッファがいっぱいになりすぎると、後続のWrite()の試行で発生する可能性があります。ソケットのClose()メソッドを呼び出すまでに遅延する可能性があります。

于 2012-12-13T14:27:53.250 に答える