如何正确使用 TcpClient ReadTimeout

本文关键字:TcpClient ReadTimeout 何正确 | 更新日期: 2023-09-27 18:36:12

在花费了比看起来合理的更多的时间来找到这个简单问题的答案之后,我想我会把我的结果留在这里,这样其他人就不必跳过我刚刚遵循的所有障碍和错误路径。

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

无论如何,我找到的所有解决方法,包括在这个网站上,都有各种方式进行某种形式的繁忙轮询,有些甚至涉及启动另一个线程来执行简单的读取调用。 对不起,我有更好的事情要做我的 CPU,而不是坐在那里忙于轮询,尤其是在打开许多插槽的情况下,所以这对我来说不是一个选择。毕竟,这不是 1990 年代初,繁忙的民意调查只是你做事的方式。如今,我们有一种称为操作系统的东西,它使用中断非常有效地处理这些类型的事情。

无论如何,在另一个切线搜索中,我偶然发现了这篇旧博客文章:

http://blogs.msdn.com/b/mflasko/archive/2006/02/20/535655.aspx

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

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

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

和解决方案:

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

虽然我仍然认为这给 API 的用户带来了不必要的负担,但至少这是我能够从我查看的数十个站点中找到的最合适的解决方案,试图找出做一个半适当的套接字 ReadTimeout。

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

如何正确使用 TcpClient ReadTimeout

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

http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.poll%28v=vs.110%29.aspxhttp://msdn.microsoft.com/en-us/library/system.net.sockets.socket.select%28v=vs.110%29.aspx