如何始终捕获在异步读取回调函数的单个操作中读取的网络流的全部内容?

时间:2013-09-05 18:19:13

标签: c# .net sockets asynchronous tcplistener

我有以下读回调函数,其中我打算读取TCP数据传输的全部内容并对这些内容执行工作。当读取任何小于8192字节的传输时,它工作得很漂亮。但是,当遇到大于8192字节的传输时,它会对前8192个字节执行工作,然后再次为后续的8192个字节运行该函数。当我在单步执行代码时检查networkStream对象时,它会显示SystemNotSupported异常; “此流不支持搜索操作。”

我意识到我的异常处理在发布的代码中很糟糕。这是现在的沙盒测试,而不是生产代码。

我希望在对数据执行工作之前捕获回调函数中的整个传输。我该怎么做?

    private void ReadCallback(IAsyncResult asyncResult)
            {
                Client client = asyncResult.AsyncState as Client;
                if (client != null)
                {
                    NetworkStream networkStream = client.NetworkStream;                
                    int read;
                    try
                    {
                        read = networkStream.EndRead(asyncResult);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                        return;
                    }

                    if (read == 0)
                    {
                        return;
                    }

                    try
                    {
                        byte[] data = new byte[read];
                        Buffer.BlockCopy(client.Buffer, 0, data, 0, read);
                        string message = win1252.GetString(data).TrimEnd('\u001a', '\r', '\n'); //decode the transmission
                    //Do work on received message here...
                    } 
                    catch (Exception ex)
                    {
                         MessageBox.Show(ex.Message);
                         return;
                    }

1 个答案:

答案 0 :(得分:1)

您不能依赖任何流来返回您在Read请求中提出的数据量。对于远程流(原始网络,HTTP,远程文件系统)尤其如此。

简单的解决方案是使用StreamReader来包装流,该流将负责正确处理来自流的部分读取以及编码。

替代解决方案 - 在网络流上包装另一个自定义流以首先读取和缓冲所有数据(请注意,在网络流的情况下,“全部”可能很难定义)。