【问题标题】:Measuring time difference between networked devices测量联网设备之间的时间差
【发布时间】:2010-09-22 05:30:10
【问题描述】:

我正在为我制作的游戏添加联网多人游戏。当服务器向客户端发送更新数据包时,我会包含一个时间戳,以便客户端确切知道该信息何时有效。但是,服务器计算机和客户端计算机的时钟可能设置为不同的时间(甚至可能只有几秒钟的差异),因此需要将来自服务器的时间戳转换为客户端的本地时间。

所以,我想知道计算服务器和客户端之间时间差的最佳方法。目前,客户端在初始化期间 ping 服务器以获取时间戳,记录请求的发送时间和响应时间,并猜测时间戳大约是在整个过程的中途生成的。客户还运行了 10 次这样的试验并取平均值。

但是,问题是我在重复运行程序时得到了不同的结果。在每组 10 个中,每个测量值的偏差很少超过 400 毫秒,这可能是可以接受的。但是,如果我在每次运行程序之间等待几分钟,则得到的平均值可能会相差 2 秒之多,这是不可接受的。

有没有更好的方法来计算两个联网设备的时钟之间的差异?或者至少有办法调整我的算法以产生更准确的结果?

可能相关或不相关的详细信息:这些设备是通过蓝牙进行通信的 iPod Touch。我正在测量 ping 的范围为 50-200 毫秒。我不能要求用户同步他们的时钟。 :)


更新:在以下答案的帮助下,我编写了一个 Objective-c 类来处理这个问题。我把它贴在我的博客上:http://scooops.blogspot.com/2010/09/timesync-was-time-sink.html

【问题讨论】:

    标签: networking


    【解决方案1】:

    我最近上了一小时的课程,但时间还不够长,但我会尽量简化,让您指出正确的方向。准备好学一点代数吧。

    根据服务器,让 s 等于时间。根据客户,让 c 等于时间。令 d = s - c。 d是添加到客户端时间以将其校正为服务器时间的内容,这是我们需要解决的问题。

    首先,我们从服务器向客户端发送一个带有时间戳的数据包。当客户端接收到该数据包时,它将给定时间戳与其自身时钟之间的差异存储为 t1。

    然后客户端向服务器发送一个带有自己时间戳的数据包。服务器将时间戳与其自身时钟之间的差异作为 t2 发送回客户端。

    请注意,t1 和 t2 都包括数据包的“旅行时间”t 加上两个时钟之间的时间差 d。假设目前两个方向的旅行时间相同,我们现在有两个未知数的两个方程,可以求解:

    t1 = t - d
    t2 = t + d
    t1 + d = t2 - d
    d = (t2 - t1)/2
    

    诀窍是因为旅行时间并不总是恒定的,正如您在 50 到 200 毫秒之间的 ping 所证明的那样。事实证明,使用具有最短 ping 时间的时间戳是最准确的。这是因为您的 ping 时间是“裸机”延迟加上在路由器队列中等待的任何延迟的总和。每隔一段时间,就会有一个幸运数据包通过,没有任何排队延迟,因此您使用该最短时间作为最可重复的时间。

    另外请记住,时钟以不同的速率运行。例如,我可以将家里的计算机重置为毫秒,一天后它会慢 8 秒。这意味着你必须不断地重新调整 d.您可以使用随时间计算的各种 d 值的斜率来计算您的漂移并在两次测量之间进行补偿,但这超出了这里的答案范围。

    希望能帮助您指明正确的方向。

    【讨论】:

    • 哇!谢谢!这正是我正在寻找的。我还不完全清楚为什么这比我原来的方法更好(虽然我相信它是),但是当我尝试它时我会在这里发帖。我认为我不需要在整个游戏过程中调整 d,但如果我需要,这应该不难做到。再次感谢!
    • 这非常有效。我发现如果我总是取最小(即最负)的 t1 和 t2 值,它与取最小的 ping 相同,所以它会收敛到正确的偏移量。我有 t1 = 客户端标记 - 服务器标记和 t2 = 服务器标记 - 客户端标记此外,我发现 iphone 漂移非常显着!在半小时内,两个设备之间的实际偏移量可能会改变多达半秒。我用联系 NTP 服务器的时钟程序验证了这一点。
    • 另请参阅Clock synchronization algorithm | Network Time Protocol - Wikipedia - 这包括上述方程、类似的算法和精美的图表。
    【解决方案2】:

    除非您可以使用一些统计方法,否则您的算法不会更准确。首先,10 可能还不够。第一个也是最简单的更改是收集 100 个传输时间样本,并丢弃 x 最长和最短的。

    要添加的另一件事是两个客户端都在每个数据包中发送自己的时间戳。然后你还可以计算他们的时钟相差多少,并检查时钟之间的平均差异。

    您还可以专门检查 STNP 和 NTP 实现,因为这些协议专门执行此操作。

    【讨论】:

    • 谢谢。我想我会尝试上面答案给出的算法,并听取您对使用多个样本的建议。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多