0

...基本的にはタイトルの内容とまったく同じです。NetworkStream.Lengthは実装されていません。代替手段は何ですか?

NetworkStream.BeginRead(...)への呼び出しを含む一連の再帰的な非同期コールバックを作成しようとしています。基本ケースに到達してすべてのバイトを受信したときを知るには、ストリーム内のバイトの長さを知る必要があります。これに対する回避策はありますか?

コード(このコードへのエントリポイントは、TcpListern.BeginAcceptTcpClient呼び出しの後に書き込まれます。:

private void StartRead(IAsyncResult ar)
{
   try
   {
      //Do an initial read:
      AsyncClient client = (AsyncClient)ar.AsyncState;
      int amountRead = 0;
      try
      {
         amountRead = client.ClientStream.EndRead(ar);
      }
      catch (IOException io)
      {
         ProcessDebugLog("Async read complete", io);
         client.ClientStream.Close();
         return;
      }
      string text = Encoding.UTF8.GetString(client.Bytes, 0, amountRead);

      //If TCP segmentation has occurred, more blocks will have
      // to get read in:
      if (client.ClientStream.Position < client.ClientStream.Length /*EXCEPTION HERE*/)
      {
         try
         {
            client.ClientStream.BeginRead(client.Bytes, 0, client.Bytes.Length, StartRead, client);
         }
         catch (IOException io)
         {
            ProcessDebugLog("Async read complete", io);
            client.ClientStream.Close();
         }
      }
      else
      {
         client.ClientStream.Close();
      }
   }
   catch (Exception ex)
   {
      ProcessDebugLog("ERROR - StartRead", ex);
   }
}
4

1 に答える 1

3

...基本的には、タイトルが言うこととまったく同じです。NetworkStream.Length は実装されていません。代替手段は何ですか?

ストリームの最後まで読み続けます。これに代わる方法はありません。ストリームが閉じられるまで、常にデータが増える可能性があります。

プロトコルを制御する場合、ストリームに複数の「メッセージ」を含めることができる場合は、各メッセージに長さのプレフィックスを付ける必要があります。(代わりに区切り文字を使用できますが、それは面倒です。)

すべてのデータを取得するまで、バイナリからテキストにデコードしないでください。またはDecoder、読み取りが文字の途中で分割された場合に備えて、「未完了」文字の状態を維持できる を使用する必要があります。

于 2012-04-03T20:07:44.690 に答える