2011-08-21 39 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個數據包,請斷開連接。