Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/303.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# 如何避免TCP套接字在断开连接时抛出SocketException?_C#_Sockets_Tcp - Fatal编程技术网

C# 如何避免TCP套接字在断开连接时抛出SocketException?

C# 如何避免TCP套接字在断开连接时抛出SocketException?,c#,sockets,tcp,C#,Sockets,Tcp,我正在做一个C服务器项目,进展很顺利 今天,我使用轮询从异步读取改为正常读取。当我阅读async时,这不是问题,但现在是 当客户端断开连接时,套接字抛出SocketException,该异常会导致相当长的延迟。如果我不阻止它抛出异常,整个服务器将冻结大约半秒钟。这似乎不值得费心,但服务器将获得相当多的连接和断开连接,因此这真的需要很长时间 现在我已经在检查Socket.Connected属性,该属性返回true,但在read方法之后返回false 那么,在尝试读取连接之前,是否有人知道如何“更新

我正在做一个C服务器项目,进展很顺利

今天,我使用轮询从异步读取改为正常读取。当我阅读async时,这不是问题,但现在是

当客户端断开连接时,套接字抛出SocketException,该异常会导致相当长的延迟。如果我不阻止它抛出异常,整个服务器将冻结大约半秒钟。这似乎不值得费心,但服务器将获得相当多的连接和断开连接,因此这真的需要很长时间

现在我已经在检查Socket.Connected属性,该属性返回true,但在read方法之后返回false

那么,在尝试读取连接之前,是否有人知道如何“更新”连接状态


PS:我发现了一个异常,只是延迟太大。

在典型的TCP开发中,连接意外关闭应该是一个异常情况。您应该考虑实现一个更优雅的系统,其中一方首先发送一条消息,表示它将断开连接,这样双方就可以在没有任何故障的情况下关闭连接。 请记住,需要活动来确定连接是否关闭。根据上的MSDN文档,该属性仅反映在尝试上一次操作时连接是否已连接


如果你在做一些非琐碎的事情,你应该用线程隔离你的连接,而不是每个连接一个线程,因为任何高流量的东西都会很快淹没系统,但是单个连接不可能垄断整个服务器,无论是由于连接启动的长时间操作还是超时过期。

在典型的TCP开发中,意外关闭连接应该是一种例外情况。您应该考虑实现一个更优雅的系统,其中一方首先发送一条消息,表示它将断开连接,这样双方就可以在没有任何故障的情况下关闭连接。 请记住,需要活动来确定连接是否关闭。根据上的MSDN文档,该属性仅反映在尝试上一次操作时连接是否已连接


如果你在做一些非琐碎的事情,你应该用线程隔离你的连接,而不是每个连接一个线程,因为任何高流量的东西都会很快淹没系统,但是单个连接不可能垄断整个服务器,无论是连接启动的长时间操作还是超时过期。

看起来套接字正在从关闭的流读取数据,可能是某种超时?
我只需要使用第二个线程,或者看看是否可以在断开连接后将超时更改为0?

看起来套接字正在从关闭的流读取某种类型的超时?
我只需要使用第二个线程,或者看看是否可以在断开连接后将超时更改为0?

所以答案是:这是不可能的?因为他们很可能会正常关闭,但如果不是这样,我也不希望延迟。基本上,是的。你的异步调用也会引发同样的异常,但我猜你可能没有通过调用EndRead来完成每个调用。我知道在使用异步调用时会导致同样的异常。但是异常是异步处理的,它不会阻塞服务器;您不应该编写只使用一个线程的服务器。出于好奇,为什么要放弃异步方法?我从来没有说过它不是单线程的。服务器将每10个可定制的客户机放在不同的线程上,并且还有大约10个不同的线程来处理特定的服务器组件。与GUI、映射、日志、数据库连接、计时等类似,但异步方法会导致每个客户机都获得一个线程,当服务器增长时,可能会获得1000多个客户机。而且电脑不能运行这么多线程。当然,它不会阻塞整个服务器,但这也取决于它运行的模式。我可以指定服务器等待每个线程完成,然后它杀死srvr。所以答案是:这是不可能的?因为他们很可能会正常关闭,但如果不是这样,我也不希望延迟。基本上,是的。你的异步调用也会引发同样的异常,但我猜你可能没有通过调用EndRead来完成每个调用。我知道在使用异步调用时会导致同样的异常。但是异常是异步处理的,它不会阻塞服务器;您不应该编写只使用一个线程的服务器。出于好奇,你为什么要搬家
异步方法?我从没说过它不是单线程的。服务器将每10个可定制的客户机放在不同的线程上,并且还有大约10个不同的线程来处理特定的服务器组件。与GUI、映射、日志、数据库连接、计时等类似,但异步方法会导致每个客户机都获得一个线程,当服务器增长时,可能会获得1000多个客户机。而且电脑不能运行这么多线程。当然,它不会阻塞整个服务器,但这也取决于它运行的模式。我可以指定服务器等待每个线程完成,然后它杀死srvr。实际上,只有在我尝试读取后,流才会被标记为关闭。这很奇怪。您是否正确地关闭了套接字?我正在关闭客户端上的套接字,而不是服务器上的套接字。我认为应该先关闭两个套接字。这就是为什么我会出现异常。。。什么是,什么应该是之间有很大的区别。事实上,在我尝试阅读之后,流才被标记为关闭。这很奇怪。您是否正确地关闭了套接字?我正在关闭客户端上的套接字,而不是服务器上的套接字。我认为应该先关闭两个套接字。这就是为什么我会出现异常。。。现在是什么和应该是什么之间存在着巨大的差异。