TcpClient.ReceiveTimeout不能处理小值?

时间:2015-04-21 22:33:48

标签: c# vb.net tcp timeout tcpclient

我尝试过以下情况,并使用秒表来确定套接字接收的实际时间。请注意,超时以毫秒为单位。

Dim NextClient As New TcpClient
NextClient.ReceiveTimeout = 1 //Case 1
NextClient.Client.ReceiveTimeout = 1 //Case 2
Dim ns As Net.Sockets.NetworkStream = client.GetStream()
ns.ReadTimeout = 1 //Case 3
Dim sw As New Stopwatch
sw.Start()
ns.Read(gbytes, 0, 5997)
sw.Stop()

BTW,ns.CanTimeout返回true。此外,我并不是真的期望1毫秒的精度,它仅用于测试目的。我实际上已经开始了500毫秒,但首先想用这个进行测试。

在所有情况下及其组合中,即使我每次用秒表测量100+毫秒,我也会收到数据,没有例外。但是,如果我故意在几秒钟内延迟响应,我就可以得到异常。但即使我对服务器的ping / 2也要超过1毫秒。

奇怪的是,如果我将超时设置为1000毫秒,服务器响应大约需要1020毫秒,则会触发异常。

那么,是否存在最小值或其他值?

2 个答案:

答案 0 :(得分:1)

MSDN:

  

ReceiveTimeout属性确定Read方法在能够接收数据之前将阻塞的时间量。此时间以毫秒为单位。如果超时在Read成功完成之前到期,则TcpClient会抛出IOException。默认情况下没有超时。

...如果我将超时设置为1000毫秒,服务器响应大约需要1020毫秒,则会触发异常。好吧,如果响应时间超过配置的超时时间,那么你就可以了。得到例外。

  

如果超出超时时间,Receive方法将抛出SocketException。

...是否有最小值或其他内容?

适用的值从-1到0变化到MAX_INT_32。

  

超时值,以毫秒为单位。默认值为0,表示无限超时时间。指定-1也表示无限超时时间。

但是,底层硬件和/或操作系统会确定超时的结果/粒度(例如,Windows通常默认的计时器分辨率为15.625 ms。因此,异常仅以15.625 ms的倍数提升。)

答案 1 :(得分:0)

Microsoft的定义似乎在这里: https://msdn.microsoft.com/en-us/library/bk6w7hs8%28v=vs.110%29.aspx

并且反对它的评论如下:

“如果读取操作未在此属性指定的时间内完成,则读取操作将抛出IOException。”

所以问题有点复杂,因为像往常一样,它依赖于准确而清晰地写出的措辞。

该定义不引用任何类型的定时器量子或任何定时器的限制,因此如果您指定超时1000mS并且在1000mS内未收到读取,则必须抛出异常,否则该机制不符合其定义

为了使其正确,任何定义都必须指定一些定时器精度值,否则没有可行的“超过”定义。仅仅因为超时被指定为整数并不意味着在1001mS之后超过了间隔 - 你可以合理地说它在1000.0000000000000001ms之后超过了。

当说“如果读取操作没有完成......”时,也没有“完整”的定义。

是否意味着它没有读取你要求的所有字节,或者,如果你要求部分阅读,是否意味着它没有读取任何内容?

它的措辞不是很好,我怀疑微软会说定义是错误的而不是函数错误,这对你没有多大帮助,因为它们可以通过一种方式改变函数在版本之间的工作方式这可能会破坏你的代码,甚至没有评论它。

如果它仍然按照描述所说的那样它仍然按照规范工作,如果你使用“未记录”的功能 - 换句话说,你观察到的事情而不是规范所说的事情 - 然后那很难。

不幸的是,这根本不符合规范所说的,所以你所能做的只是使用并利用其“观察到的行为”并希望它保持不变。