1

データを非同期的に読み取るための C# TcpClient があります。簡略化したコードは次のとおりです。

public async Task StartReading(CancellationToken token)
{
    // To fit the largest package
    const int BufferSize = 524288;

    while(true)
    {
         var buffer = new byte[BufferSize];
         int bytesRead = await this.networkStream.ReadAsync(buffer, 0, BufferSize);
                                          .WithWaitCancellation(token);            

            if (bytesRead > 0)
            {
                 Console.Read(string.Fromat("{0} bytes received."));

                 // Run processing at background process
                 Task.Run(() => ProcessData(buffer, bytesRead));
            }
            else
            {
                // If received 0 bytes then a tcp connection is terminated
                break;
            }
    }
}

受信したパッケージには、STX で始まり ETX で終わる 1 つ以上のメッセージが含まれる場合があり、パッケージの長さは送信されません。このフィードはサードパーティによって提供され、変更されることはありません。

テスト中に、サーバーがデータを 8192 チャンクで送信するように見えたため、メッセージが 2 つの後続のチャンクに分割され、処理に失敗する可能性がありました。
ログは次のとおりです。
8192 バイトの受信
メッセージ 89 の処理 / 1 失敗
8192 バイトの受信
メッセージ 89 の処理 / 2 の失敗
8192 バイトの受信
メッセージ 89 の処理 / 2 の失敗
2349 バイトの受信
メッセージ 34 の処理 / 1 の失敗

同期読み取りも役に立ちません。どうすれば管理できますか?

4

1 に答える 1

5

基本的に、TCPはストリームベースのプロトコルです。あなたはそれをパケットベースのプロトコルとして扱わせようとしています。そうしないでください。

データは独自の区切り文字を提供するので、それを使用します。メッセージが完全に受信されていない場合は、それらのバイトを記憶し、メッセージの残りの部分が受信されたときにそれらを処理します。(次の読み取り呼び出しでもメッセージが完全に受信されない可能性があることに注意してください...)

于 2013-02-28T20:16:33.100 に答える