我目前在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中被调用,我的应用程序可以接收来自服务器的消息作为通知,因此我必须始终在阅读传入消息(我不知道通知何时到达)。