2010-09-20 36 views
12

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

所以,我想知道计算服务器和客户端之间时差的最佳方法。目前,客户端在初始化过程中向服务器发送一个时间戳记,记录了请求的发送时间和应答时间,并且猜测时间戳记大概是在旅途中途产生的。客户也运行这些试验中的10个,并取平均值。

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

有没有更好的方法来找出两个联网设备的时钟之间的差异?还是至少有一种方法来调整我的算法,以产生更准确的结果?

可能相关或不相关的细节:设备是通过蓝牙进行通信的iPod Touch。我测量的平均值是50-200毫秒。我不能要求用户同步他们的时钟。 :)


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

回答

23

我最近在这上面花了一个小时的课,但时间还不够长,但我会尽量让它指向正确的方向。准备好一个小代数。

让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 

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

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

希望能帮助你指出正确的方向。

+0

哇!谢谢!这正是我要找的。对我来说这并不完全清楚,但为什么这比我最初的方法更好(虽然我相信它),但是当我尝试时我会回到这里。我认为我不需要在整个游戏过程中进行调整,但如果需要的话,应该不难做到。再次感谢! – whooops 2010-09-21 00:19:56

+0

这工作得很好。我发现,如果我总是采用最小(即最负)的t1和t2值,这与采用最小的ping相同,所以它会收敛到正确的偏移量。 我已经 T1 =客户邮票 - 服务器邮票 和 T2 =服务器邮票 - 客户端邮票 另外,我发现,iPhone手机相当显著漂移!在半小时内,两台设备之间的实际偏移可能会改变半秒钟。我使用与NTP服务器联系的时钟程序对此进行了验证。 – whooops 2010-09-21 20:28:49

+0

很高兴它对你有帮助。 – 2010-09-21 20:35:48

2

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

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

您也可以特别检查STNP和NTP实现,因为这些协议专门用于此目的。

+0

谢谢。我想我会尝试上面的答案给出的算法,并采用多个样本的建议。 – whooops 2010-09-21 00:23:03