Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.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# 如何正确使用TcpClient ReadTimeout_C#_.net_Tcpclient - Fatal编程技术网

C# 如何正确使用TcpClient ReadTimeout

C# 如何正确使用TcpClient ReadTimeout,c#,.net,tcpclient,C#,.net,Tcpclient,在花了太多的时间来找到这个简单问题的答案后,我想我会把我的结果留在这里,这样其他人就不必跳过我刚才走过的所有障碍和错误的道路 问题是,如果您使用TcpClient ReadTimeout属性,并且您的读取操作实际上超时,则Microsoft决定关闭套接字。这不是预期的,不可取的,我所知道的任何其他套接字实现都没有做到,并且除了程序员的懒惰之外,没有任何有效的理由认为应该是这种情况。但这正是微软选择做的 无论如何,我发现的所有变通方法,包括在这个网站上,都有各种各样的方式来进行某种形式的繁忙轮询,

在花了太多的时间来找到这个简单问题的答案后,我想我会把我的结果留在这里,这样其他人就不必跳过我刚才走过的所有障碍和错误的道路

问题是,如果您使用TcpClient ReadTimeout属性,并且您的读取操作实际上超时,则Microsoft决定关闭套接字。这不是预期的,不可取的,我所知道的任何其他套接字实现都没有做到,并且除了程序员的懒惰之外,没有任何有效的理由认为应该是这种情况。但这正是微软选择做的

无论如何,我发现的所有变通方法,包括在这个网站上,都有各种各样的方式来进行某种形式的繁忙轮询,有些甚至涉及启动另一个线程来执行一个简单的读取调用。我很抱歉,但我有更好的事情来处理我的CPU,而不是坐在那里忙着投票,特别是在许多套接字打开的情况下,所以这不是我的选择。毕竟,这不是20世纪90年代初,繁忙的投票只是你做事的方式。现在,我们有一种叫做操作系统的东西,它可以非常有效地利用中断来处理这类事情

无论如何,在另一次切题搜索中,我偶然发现了这篇老博文:

MSDN博客>Mike Flasko的博客>读取网络数据时处理超时

告诉您如何正确处理读取超时的解决方案的关键要点包括:

此时,可能会尝试捕获异常,然后在同一网络流上重新发出读取。此策略可能导致意外错误。现在最好的做法是将NetworkStream(套接字)视为处于不稳定状态。这是因为当底层堆栈超时时,底层I/O读取被取消。如果数据同时进入,数据将丢失,导致数据流损坏

解决方案是:

更好的方法是捕获异常,关闭套接字或TCPClient,必要时重新连接

虽然我仍然认为这会给API的用户带来不必要的负担,但至少这是我在几十个站点中找到的最合适的解决方案,我试图找出一个半合适的套接字读取超时


我希望这个问题/评论可以节省我查找的时间。

您需要的是Poll或Select方法,这些方法允许您在不关闭基础连接的情况下等待超时的数据:


我最近也在使用这些东西,如果我将超时设置为1000毫秒并捕获异常,有时我可能会延迟一些过程,因为很难确定传输是否真的结束或您遇到了网络问题。例如,我有一部分代码通过网络传输PNG图像,代码类似于while(true){尝试接收数据并放入4096字节的缓冲区,在异常时中断;如果没有可用数据,则中断while;}如果我没有放入1ms线程睡眠,(我知道这很糟糕)可用数据将很快返回false,图像将被篡改。这是一个问题吗?我觉得如果采用问答形式,即使你在回答自己的问题,也会更好。题目就是问题。我当然可以问这个问题,并在一个单独的回答,但我这样做了。这是我要问的原始问题,但在按下Post按钮之前,我认为我应该做足够的研究,这样我可以问一个更“知情”的问题。然而,我没有意识到这小小的努力最终会花费多少时间。在这个过程中,我回答了自己的问题。由于花了这么长时间才想出一个可接受的解决方案,我认为让其他人不用重复我必须做的所有小时的研究是很好的……另一种选择是根本不提这个问题。但我认为这对其他人会有帮助。@Dunk谢谢你的问答帖子,我现在正在努力解决这个问题。我使用ReadTimeout属性编写TCP服务器客户端应用程序,捕获异常并在同一NetStream上重新发出读取。有趣的是,它在Win7上工作,但在WinXP中不工作。在Win XP上收到ReadTimeout发出的IOException后,套接字将被关闭。