2011-08-21 52 views
1

我有一个客户端,每8秒会发送一个数据包到服务器。如果服务器检测到数据包发送太快,它将断开客户端连接。在客户端我叫睡眠(8000);在发送数据包之前。在服务器端我使用GetTickCount();来计算数据包之间的时间。我预计这工作没有任何问题,但我一直断开连接。数据包计时问题

我使用Wireshark来检查数据包的时间,这是我得到了什么: 包号时间 17 8.656064 72 16.957240 115 24.764741

24.764741 - 16.957240 = 7.807501 < 8就是为什么我被断开的原因。 我不明白这一点,因为在客户端我叫睡眠(8000);所以它应该每8秒或更多时间发送一次数据包。

第二个数据包迟了0.3秒,第三个数据包早约0.2。 有没有办法及时发送这些数据包?

+2

总之,没有。这是一个完全不确定的系统。路径中的任何组件(并且有很多)都不会有任何硬性保证。你将不得不添加一个模糊因素。 – Nim

回答

1

问题其实是一个古老的问题;计时单位计数变化,甚至多个CPU之间在同一台计算机:

http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/22c68353-1dbb-4718-a8d2-0679fdc0c298/

我的建议是设置你的睡眠,以高于8000,说9500,并保持计时单位计数相同的技工,因此睡眠应该总是更高。

另一个链接来阅读是在这里:

http://en.wikipedia.org/wiki/Latency_(engineering)#Computer_hardware_and_operating_system_latency

具体参考Microsoft Windows上的段落。

更新:

我不知道这是为什么越来越downvoted,但让我澄清这个问题,在我看来,这里。

TickCount不能作为时间的特定度量,除非它被本地化为一个处理单元。 MSDN的第一个链接提供了为什么引用。其次,Windows本身可能在其定时器逻辑中有不准确之处。

最后,基于晶体的定时器本身可能会有所不同,因为已知大气条件会影响压电振荡。

http://en.wikipedia.org/wiki/Crystal_oscillator#Temperature_effects

综上所述,计时单位计数是不可靠的,获得绝对精度在通过网络发送的数据包是一个很难的事情,以实现在消费级网络。

我的解决方案,以确保睡眠计时器等待更长的时间,然后滴答定时器不是优雅,但足以'解决'问题。

你不能保证数据包将X秒内到达,但你可以使非常肯定,在一定时间经过的时候,才不会被发送。

+0

Downvoter关心评论? –

+0

+1 Windows计时从来都不是很准确,但考虑使用多媒体计时器或各种等待API会更好。 –

1

对我来说,你会期望这工作似乎很奇怪。例如,尽管延迟,你的数据包可能会被缓冲并通过线路一起发送。取决于网络条件,他们可能无序到达或任意延迟。它们之间有多少时间在服务器端进行处理时有什么关系?服务器上的时间并没有说明客户端的时间。

2

答案建议您不要过分依赖时钟精度并了解延迟源是否正确。

然而,事实上,你是出由200毫秒让我猜测,你正在使用TCP和你没有关闭Nagle算法。对于时间敏感的协议,您应该设置您的套接字使TCP_NODELAY打开。

所有其余的TCP延迟警告适用;你不知道什么时候会发生,你需要在协议中处理这些事情。

0

你不能指望在网络上发送的单个数据包被准确定时。而不是根据最后两个数据包之间的时间设置断开连接条件,而是平均延长一段时间 - 例如,如果在最后40秒内收到超过5个数据包,请断开连接。