C#NetworkStream ReadAsync,在缓冲区之间拆分数据

时间:2018-09-29 19:58:16

标签: c# .net task tcpclient networkstream

我目前在NetworkStream中使用ReadAsync方法,因此到目前为止它非常稳定。当从服务器接收的数据大于缓冲区本身时,会发生此问题。

ReadCallBack假定缓冲区包含完整且有效的消息,因为在每次对BeginAsyncRead的调用上都会创建一个新缓冲区。因此,当响应对于一个缓冲区太大时,它会在多个读取之间分配,因此会在多个缓冲区之间分配。

然后,我的ReadCallBack假定每个缓冲区都是一条独立的消息(而不是将它们添加在一起),并最终导致两个缓冲区的反序列化失败。

我的问题是处理大于缓冲区大小的消息的正确方法是什么,特别是如果要异步读取消息的话? 字符本身可以在两个缓冲区之间分割,因此这非常棘手。

下面是我的ReadAsync和ReadCallBack代码。

    public async Task ReadForever() {
        while(this.IsConnected) {
            await BeginAsyncRead();
        }
    }


    public async Task BeginAsyncRead() {
        if (this.Stream.CanRead) {
            try {
                ReceiverState readState = new ReceiverState(this.Stream);
                var task = this.Stream.ReadAsync(readState.buffer, 0, ReceiverState.bufferSize);
                await task.ContinueWith(bytesRead => ReadCallBack(bytesRead.Result, readState));
            }
            catch (Exception e) {
                Console.WriteLine("Error");
            }
        } else {
            Console.WriteLine("Unreadable stream");
        } 
    }

private void ReadCallBack(int numBytesRead, ReceiverState state) {
    if (numBytesRead > 0) {
        string payload = Encoding.ASCII.GetString(state.buffer, 0, numBytesRead);
        string[] responses = payload.Split(new string[] {"\n"}, StringSplitOptions.RemoveEmptyEntries);
        foreach (string res in responses){                    
            var t = Task.Run(() => this.OnRead(res));
        }
    } else {
        Console.WriteLine("Corrupted number of bytes received");
    }
}

注意:服务器发送的所有响应末尾都包含换行符。 注意:ReadForever在Task.Run中被调用,我的应用程序可以接收来自服务器的消息作为通知,因此我必须始终在阅读传入消息(我不知道通知何时到达)。

0 个答案:

没有答案