我正在为我制作的游戏添加联网多人游戏。当服务器向客户端发送更新数据包时,我会包含一个时间戳,以便客户端确切知道该信息何时有效。但是,服务器计算机和客户端计算机的时钟可能设置为不同的时间(甚至可能只有几秒钟的差异),因此服务器的时间戳需要转换为客户端的本地时间。
所以,我想知道计算服务器和客户端之间时差的最佳方法。当前,客户端在初始化期间对服务器执行时间戳记录,记录请求何时被发送以及何时被应答,并且猜测时间戳大致在旅程的中途生成。客户还运行其中10个试验并取平均值。
但是,问题是我在重复运行程序时会得到不同的结果。在每组10中,每次测量很少发生超过400毫秒的偏差,这可能是可以接受的。但是,如果我在每次运行程序之间等待几分钟,结果平均值可能不同意多达2秒,这是不可接受的。
有没有更好的方法来确定两个联网设备的时钟之间的差异?或者至少有一种方法可以调整我的算法以产生更准确的结果吗?
可能相关或不相关的详细信息:这些设备是通过蓝牙进行通信的iPod Touch。我测量的ping是50-200毫秒。我不能要求用户同步他们的时钟。 :)
更新:借助以下答案,我写了一个objective-c类来处理这个问题。我在我的博客上发布了它:http://scooops.blogspot.com/2010/09/timesync-was-time-sink.html
答案 0 :(得分:24)
我最近上了一个小时的课程并且时间不够长,但是我会尝试将它煮沸以使你指向正确的方向。为一个小代数做好准备。
让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值的斜率来计算您的漂移并在两次测量之间进行补偿,但这超出了答案的范围。
希望这有助于指明你正确的方向。
答案 1 :(得分:2)
除非您可以使用某些统计方法,否则您的算法将不会更准确。首先,10可能还不够。第一个也是最简单的改变是收集100个过境时间样本,然后抛出x最长和最短的样本。
要添加的另一件事是两个客户端都在每个数据包中发送自己的时间戳。然后你还可以计算它们的时钟差异,并检查时钟之间的平均差异。
您还可以专门检查STNP和NTP实现,因为这些协议专门执行此操作。