Phi*_*aré 5 c# asynchronous tcp
我最近开始使用新的C#5.0"async"和"await"关键字.我以为我得到了扭曲,但意识到有一件事让我怀疑.这是我从远程TcpClient异步接收数据的方式.一旦我接受连接,我就调用这个函数:
static async void ReadAsync(TcpClient client)
{
NetworkStream ns = client.GetStream();
MemoryStream ms = new MemoryStream();
byte[] buffer = new byte[1024];
while(client.Connected)
{
int bytesRead = await ns.ReadAsync(buffer, 0, buffer.Length);
ms.Write(buffer, 0, bytesRead);
if (!ns.DataAvailable)
{
HandleMessage(ms.ToArray());
ms.Seek(0, SeekOrigin.Begin);
}
}
}
Run Code Online (Sandbox Code Playgroud)
收到数据后,循环就会继续运行而不会读取任何内容.我在循环中用Console.WriteLine测试了这个.我正确使用它吗?我觉得我不应该使用while循环...
该TcpClient.Connected值不会立即更新。根据 MSDN:
true如果客户端套接字在最近的操作中连接到远程资源;否则,false。
所以有TcpClient.Connected一个 while 循环条件不是一个好的选择。
TcpClient.DataAvailable 用于同步操作,不用于异步操作。
将您的代码更新为:
static async void ReadAsync(TcpClient client)
{
NetworkStream ns = client.GetStream();
MemoryStream ms = new MemoryStream();
byte[] buffer = new byte[1024];
while(true) {
int bytesRead = await ns.ReadAsync(buffer, 0, buffer.Length);
if (bytesRead <= 0)
break;
ms.Write(buffer, 0, bytesRead);
HandleMessage(ms.ToArray());
ms.Seek(0, SeekOrigin.Begin);
}
}
Run Code Online (Sandbox Code Playgroud)
当ReadAsync返回 0 时,表示 TCP 连接关闭或关闭。在 MSDN 中:
该
TResult参数的值包含读入缓冲区的总字节数。如果当前可用的字节数小于请求的数量,则结果值可能小于请求的字节数,如果已到达流的末尾,则结果值可以为 0(零)。