C#TcpClient ReadAsync读取大型消息

时间:2013-02-28 20:13:34

标签: c# asynchronous tcpclient

我有一个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结尾的消息,不会发送包长度。此Feed由第三方提供,不会更改。

在测试期间,似乎服务器以8192个块发送数据,因此消息可能被分成两个后续的块并且无法处理。
这是一个日志:
收到8192个字节
消息89处理/ 1失败
收到8192个字节
消息89处理/ 2失败
收到8192个字节
消息89处理/ 2失败
收到2349字节
消息34处理/ 1失败

同步阅读也无济于事。我该如何管理?

1 个答案:

答案 0 :(得分:5)

基本上,TCP是基于流的协议。您正试图将其视为基于数据包的协议。不要那样做。

数据提供了自己的分隔符 - 所以使用它。如果未完全收到消息,请记住这些字节,然后在收到其余消息时处理它们。 (请记住,下次读取呼叫时可能无法完全接收到该消息......)