如何正确使用TcpClient ReadTimeout

时间:2012-06-01 15:30:16

标签: c# .net tcpclient

在花费更多时间而不是合理地找到这个简单问题的答案后,我想我会把结果留在这里,以便其他人不必跳过我刚刚遵循的所有箍和错误的路径。 / p>

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

无论如何,我发现的所有变通方法,包括在这个网站上,都有各种方式进行某种形式的忙碌轮询,有些甚至涉及开始另一个线程来执行简单的Read调用。对不起,但是我的CPU有更好的事情,而不是坐在那里忙碌的民意调查,特别是打开很多套接字,所以这对我来说不是一个选择。毕竟,这不是1990年代早期的繁忙民意调查就是你做事的方式。如今,我们有一个叫做操作系统的东西,可以使用中断非常有效地处理这些类型的事情。

无论如何,在另一次切向搜索中,我偶然发现了这篇旧帖子:

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

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

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

  

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

和解决方案:

  

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

虽然我仍然认为这给API的用户带来了不必要的负担,但至少它是我能够找到的几十个网站中找到的最合适的解决方案,我试图找出做半正式的socket ReadTimeout。

我希望这个问题/评论可以节省一些人花在我身上的时间。

1 个答案:

答案 0 :(得分:2)

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

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