Networking 测量联网设备之间的时间差

Networking 测量联网设备之间的时间差,networking,Networking,我正在将网络多人游戏添加到我制作的游戏中。当服务器向客户机发送更新包时,我会包含一个时间戳,以便客户机准确地知道该信息何时有效。但是,服务器计算机和客户端计算机的时钟可能设置为不同的时间(甚至可能只有几秒钟的差异),因此需要将服务器的时间戳转换为客户端的本地时间 因此,我想知道计算服务器和客户端之间时间差的最佳方法。目前,客户机在初始化期间为服务器ping一个时间戳,记录请求何时发送和何时应答,并猜测时间戳大约是在旅程的中途生成的。客户还进行了10次试验,并取平均值 但是,问题是我在程序的重复运

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

因此,我想知道计算服务器和客户端之间时间差的最佳方法。目前,客户机在初始化期间为服务器ping一个时间戳,记录请求何时发送和何时应答,并猜测时间戳大约是在旅程的中途生成的。客户还进行了10次试验,并取平均值

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

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

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



更新:在以下答案的帮助下,我编写了一个objective-c类来处理这个问题。我把它贴在我的博客上:

除非你能使用一些统计方法,否则你的算法不会精确得多。首先,10个可能还不够。第一个也是最简单的改变是收集100个运输时间样本,然后扔掉x个最长和最短的样本

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


您还可以具体检查STNP和NTP的实现,因为这些协议都是这样做的。

我最近在这方面上了一个小时的课,时间还不够长,但我会尝试将其归结为正确的方向。准备学一点代数

让我们根据服务器来计算时间。让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值的斜率来计算漂移,并在测量之间对其进行补偿,但这超出了这里的回答范围


希望这能帮你指明正确的方向。

Wow!谢谢这正是我要找的。我还不完全清楚为什么这比我原来的方法好(尽管我相信是的),但我会在试用后再发回来。我不认为我需要在整个游戏过程中调整d,但如果我需要的话,这应该不难做到。再次感谢!这真的很有效。我发现如果我总是取最小的(即最负的)t1和t2值,它与取最小的ping值相同,因此它收敛于正确的偏移量。我有t1=客户端戳记-服务器戳记和t2=服务器戳记-客户端戳记,我发现iPhone的漂移非常明显!在半小时内,两台设备之间的实际偏移量可能会改变半秒之多。我通过与NTP服务器联系的时钟程序验证了这一点。谢谢。我想我会尝试上面答案给出的算法,并听取您关于使用多个样本的建议。