2012-02-21 9 views
1

私は私が午前問題はを読むことである非同期ソケットの読み取りが終了したときは、どうすればわかりますか?接続が閉じている場合

private void read(IAsyncResult ar) { 
     //Get the Server State Object 
     ServerState state = (ServerState)ar.AsyncState; 

     //read from the socket 
     int readCount = state.socket.EndReceive(ar); 

     //check if reading is done, move on if so, trigger another read if not 
     if (readCount > 0) { 
      //purge the buffer and start another read 
      state.purgeBuffer(); 
      state.socket.BeginReceive(state.buffer, 0, ServerState.bufferSize, 0, new AsyncCallback(read), state); 
     } 
     else { 
      //all bytes have been read, dispatch the message 
      dispatch(state); 
     } 
    } 

...非同期readメソッドを持っているだけで0です。どのようにすれば、これがそのメッセージの終わりで、ディスパッチャにデータを渡し、新しいメッセージを受け入れるためにソケットを開いたままにしておきます。

ありがとうございました!

答えて

4

TCPバッファにあるものに頼るべきではありません。着信バイトはストリームのどこかで処理する必要があります。あなたは本当にその完全なものかどうかを知ることはできません。上記の1つの層だけが、メッセージがいつ完了したかを知ることができる。

例: HTTP応答を読み取った場合、HTTPヘッダーにはHTTP本文に含まれるバイト数が含まれます。だからあなたはどれくらい読むべきかを知っている。

データが特定のプロトコルに準拠していて、それを解釈する場合、どれくらい読みとるべきか分かります。ソケットを介してファイルを受け取ったとします。最初に受け取るのはファイルサイズです。それがなければ、どれくらい読むべきか分かりません。

+0

メッセージが届いたら、メッセージの長さを送信する必要があります。 – Dabloons

+0

それはまさにそれです。それがなければ、インターネットのラジオストリームのオーディオストリームのようなデータの流れはまったくありません。 – BlueM

0

メッセージは、開始時と終了時を区別できるように特定の形式にする必要があります。たとえそれがデータの流れであったとしても、それはパケットで送られるべきです。

メッセージの長さを最初に送信してから、どれくらいのデータが必要なのかを知ることができます。しかし、それに伴う問題は、同期が緩やかで復旧できず、メッセージの長さと内容が分からない場合です。メッセージがいつ始まるかを知るために、特別なマーキングシーケンスを使用することは良いことです。 100%エラープルーフではありませんが(シーケンスがデータに表示される可能性がありますが)確かに役立ち、同期の緩みから回復することができます。これはソケットのようなバイナリストリームから読み込むときに特に重要です。

古代のRS232シリアルプロトコルであっても、すべてのデータをいつ取得したのかを知るためのフレームとストップビットがありました。

関連する問題