Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
TCP客户;网络流;ReadAsync;C#_C#_Tcpclient_Beginread - Fatal编程技术网

TCP客户;网络流;ReadAsync;C#

TCP客户;网络流;ReadAsync;C#,c#,tcpclient,beginread,C#,Tcpclient,Beginread,请原谅我缺乏关于任务和异步的知识 使用TcpClient类,我正在创建与可用服务器的连接: void async RunClientAsync() { TcpClient client = new TcpClient(); try { await client.ConnectAsync(IPAddress.Parse("1.1.1.1"), 8889); Task.Start(() => ReadClientAsync(client)

请原谅我缺乏关于任务和异步的知识

使用TcpClient类,我正在创建与可用服务器的连接:

void async RunClientAsync()
{
    TcpClient client = new TcpClient();
    try
    {
        await client.ConnectAsync(IPAddress.Parse("1.1.1.1"), 8889);
        Task.Start(() => ReadClientAsync(client));
    }
    catch (Exception ex)
    {
        HandleException(ex);
    }
}

// -----

void async ReadClientAsync(TcpClient client)
{
    byte[] bf = new byte[2048];
    try
    {
        while(true)
        {
            int br = await client.NetworkStream().ReadAsync();
            if (br > 0) 
            {
                HandleInboundData(bf, br);
            }
        }
    }
    catch (Exception ex)
    {
        HandleException(ex);
    }
}
助手方法HandleException(Exception ex)和HandleInboundData(byte[]buffer,int length)将执行假定的任务

与服务器的连接将是永久性的,从服务器接收的数据的长度和频率未知,其想法是抛出一个任务,该任务仅在数据可用时接收和处理入站数据

ReadClientAsync(TcpClient client)显然失败,因为如果没有可用数据,ReadAsync将始终返回0字节

我应该如何使用async/task编写ReadClientAsync来防止繁忙的循环情况?我以前在这些情况下使用过BeginRead/EndRead,效果很好。在这种特殊情况下,这就是解决方案吗


谢谢,

不,TCP不是这样工作的

NetworkStream
被认为在另一方启动(可能是单向)关机时处于“流结束”状态。这就是
ReadAsync
(或
Read
)返回零的时候,而不是在任何其他情况下

MSDN文档很容易被误解——主要是因为您看到的文档是错误的
NetworkStream
不会覆盖
ReadAsync
(没有理由这样做),因此您实际上正在查看通用
流的文档。ReadAsync
。相比之下,
NetworkStream.Read
的文档说明:

此方法将数据读入缓冲区参数,并返回成功读取的字节数。如果没有可读取的数据,Read方法返回0。读取操作读取尽可能多的可用数据,最大读取量为size参数指定的字节数。如果远程主机关闭连接,并且已收到所有可用数据,则读取方法立即完成并返回零字节

请注意最后一句,它告诉您
网络流
为“流的结束”的实际含义。这就是TCP连接关闭的方式

对此的响应通常也应该是关闭另一端的连接-
从helper方法返回
,并清理套接字。在任何情况下,不要再次重复
while(true)
——您只会得到一个占用100%CPU的无限循环


如果您想要一些关于如何使用
wait
处理C#异步套接字的指南,请查看我的示例。请注意免责声明-这绝不是生产准备就绪。但它确实解决了人们在实现TCP通信时经常犯的一些错误。

谢谢您的评论。这来自ReadAsync的MSDN条目:“表示异步读取操作的任务。TResult参数的值包含读入缓冲区的总字节数。如果当前可用字节数小于请求的字节数,则结果值可以小于请求的字节数,也可以为0(零)如果已到达流的末端。“我理解“流结束”意味着流中没有要读取的数据。理解。谢谢Luaan。我相信我理解问题所在。您如何在10秒后超时以使ReadAsync或WriteAsync或ConnectAsync超时。换句话说,它们要么成功完成,要么在10秒后超时?