Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.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
C# 网络流如何检测断开连接_C#_Sockets_Asynchronous_Tcp_Network Programming - Fatal编程技术网

C# 网络流如何检测断开连接

C# 网络流如何检测断开连接,c#,sockets,asynchronous,tcp,network-programming,C#,Sockets,Asynchronous,Tcp,Network Programming,我最近开始研究socket编程,并编写了一个简单的异步tcp服务器,它可以很好地从各个客户端发送接收。以下是它的简化代码: //accpet loop while (true) { var client = await listener.AcceptTcpClientAsync(); new AppClient(client).Start(); } // and here is the start method in AppClient class public async

我最近开始研究socket编程,并编写了一个简单的异步tcp服务器,它可以很好地从各个客户端发送接收。以下是它的简化代码:

//accpet loop

while (true)
{
   var client = await listener.AcceptTcpClientAsync();
   new AppClient(client).Start();
} 

 // and here is the start method in AppClient class
 public async void Start()
 {
        /// TcpClient is a class property which is in scope of this method
       using (var stream = TcpClient.GetStream())
       {
           string message = string.Empty;
           byte[] buffer = new byte[1000];
           int bytesRead = 0;
           while (true)
           {
                try
                {
                    bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false);
                }         
                catch (Exception ex)
                {
                        MessageBox.Show(ex.Message);
                        break;
                 }

                 // decode simple text message
                 message += Encoding.UTF8.GetString(buffer, 0, bytesRead);


           }
       }
  }
它以单线程方式处理数千个连接,但 让我不安的是,无论我如何破坏客户端(杀死进程和…),ReadAsync方法都会立即抛出一个与我的想法基本冲突的异常。 (据我所知,在tcp中检测断开的套接字应该不是那么容易)

我做错了什么吗?

它不是“检测”断开连接,而是显示异常,因为
.ReadAsync
不断尝试获取是否有数据可读取,是否有数据写入缓冲区,如果数据长度==缓冲区长度,则结束函数。所有这些步骤(可能还有更多)都涉及
,它绑定到
套接字
。然后,如果套接字已关闭(通过代码或手动关闭),则流已关闭,如果您尝试对关闭的流执行任何操作,则将引发异常

您应该将与cancellationToken一起使用。然后更改循环以同时检查令牌值。当你想杀死客户端时,你就给令牌发信号

同时检查变量
bytesRead
。如果返回为
0
,则连接刚刚关闭

让我不安的是,无论我如何毁掉客户 (终止进程和…)ReadAsync方法立即抛出 例外情况

欢迎使用网络(套接字)编程。您必须让自己对这些异常感到舒适,因为在这些类型的应用程序中遇到异常是非常常见的。这种行为是故意的

您的应用程序应该在这样的情况下开发:最终用户得到的是好消息,而不是异常消息

…ReadAsync方法立即引发异常,该异常 基本上与我的想法冲突。(据我所知) tcp中断开连接的套接字不应该那么容易)

原因是:

获取上次I/O操作时客户端套接字的连接状态。当返回false时,客户端套接字要么从未连接,要么不再连接

由于Connected属性仅反映最近一次操作时的连接状态,因此应尝试发送或接收消息以确定当前状态。消息发送失败后,此属性不再返回true


请注意,这种行为是出于设计。您无法可靠地测试连接的状态,因为在测试和发送/接收之间,连接可能已丢失。你的代码应该假设套接字已连接,并能优雅地处理失败的传输。

你真的不应该做
catch(Exception ex)
-这是一种反模式。谢谢,我会记住这一点。对于他所做的事情,只要我等待它,就捕捉Exception readasync检查绝对没有错,一旦套接字上的数据可用,就会执行方法id的其余部分。非常感谢取消提示。但是bytesRead从不为零,带有wait的ReadAsync方法会暂停该方法,直到有东西要读取为止。顺便说一句,如果服务器端断开连接,它将返回0。感谢您的响应,在无限循环中使用wait stream.ReadAsync()可以吗?(我这样做是为了不断监听来自客户端的新数据)@SHM-是的,没问题。若客户机发送数据的次数事先不知道,那个么是的,您必须一直等待并接收数据。一旦客户端关闭套接字,您的循环就会中断,从而引发异常。@SHM-另外,请仔细耐心地重新阅读我的答案的最后两段。这些话很有帮助。祝你在网络编程方面的经验好运。是的,我读到了,不管多么优雅地接近=发送一个接近的数据包。现在,如果客户端没有机会将关闭数据包发送到tcp,ReadAsync如何抛出“强制关闭异常”@SHM-如果客户端没有机会将关闭数据包发送到tcp,ReadAsync如何抛出“强制关闭异常”是什么意思?引用MSDN source的话:
Close方法将实例标记为已释放,并请求关联的套接字关闭TCP连接。基于LingerState属性,在调用Close方法后,当数据仍有待发送时,TCP连接可能会保持打开状态一段时间。当基础连接完成关闭时,不提供任何通知