« Ringbuffer 范例 | 返回首页 | Lua int64 的支持 »

如何更准确的网络对时

这个周末 想到这个问题, 是由另一个问题引起的.

为了模拟复杂的网络环境,我们在内网安装了模拟环境

怪物公司同学周末调试客户端时,修改了自己机器的网关,增加了模拟延迟。奇怪的是,他的客户端在切换网关时并没有断开连接。可延迟也果真发生了。

我和他探讨了一下,觉得这个模拟延迟是单向的。当游戏服务器发送数据包回桌面时,由于服务器和他的桌面机在同一个网段,所以 IP 包被直接发回了。TCP 连接也不因为修改了过去的通路和断开。

当然,这种模拟并不是我们想要的。正确的方法应该是在修改网关(指向延迟模拟机器)的同时,也修改桌面机的 IP ,或是给自己机器绑定两个 IP ,使用模拟环境网段的 IP 来重新建立 TCP 连接。或者在模拟网关上做一次 NAT 。反正方法有很多,不展开讨论了。只有正确的模拟双向延迟(或网络颠簸)才好得到接近现实情况的场景。

不过这次错误,引出我另一个思考。如果 TCP 上行和下行延迟差距较大,有没有什么特别糟糕的事情发生呢?我的第一反应是,网络对时不准了。

我们的对时协议一般都遵从这样一个假定。我们的桌面机发送一个数据包到服务器所需要消耗的时间,大约等于服务器发一个数据包回桌面机的时间。这样,我们测试出一个数据包来回的时间,除 2 ,就得到了单程时间。这样就可以根据时间服务送来的服务器时间,把桌面时间和服务器时间基本校准了。

可一旦上下行速度不一致,甚至偏差较大时,这个假定被破坏掉了,时间也无法校准了。


有没有什么办法可以知道 A 点到 B 点的单程时间呢?如果只有 A 和 B 存在,似乎永远都无法测准。你很难知道 A 到 B 的开销是不是和 B 到 A 的开销相同。除非双程时间特别短(至少有一次特别快),误差就不会超过这个双程时间了。极端情况是,A 到 B 特别慢,而 B 到 A 是瞬间到达的。(有如我前面提到的情况,A 到 B 经过了一个故意的延迟,而 B 到 A 走了局域网的另一条路,瞬间抵达了)

我认为,如果能增加足够多的第三方路径,就能提高这个校对精度。

假定,我们有另外几台服务器,C D E 。A 向其发的包,它们都立刻把包转发到 B ; 反过来,B 发过来的包,也都立刻转到 A 。

那么,我们就可以制造出几条间接连接 A B 的不同路径。

我们假定,互联网上,两个 IP 间的通讯时间,双向延迟接近是常态,而时间不同是例外的话;就可以让对时包走不同的路径从 A 到 B ,可以推算出不同路径的单向时长(假定是双向时长的一半)。

估算出每条路径的延迟后,我们同时从 A 走不同的路径发送校时包到 B 。由于不同路径的延迟不同,B 会先后收到来源于 A 的包。如果认为前面假定成立,那么,相互比对,就可以除掉那些不稳定的路径,最终可以推算出 A 到 B 的直接连接路径上的单程时长了。


周末瞎想而已,不必当真 :)

Comments

记录客户端时间a (客户端)
记录接收到客户端时间b (服务端)
记录接收到服务端消息时间c (客户端)

b==(c-a)/2+a==c-(c-a)/2 上下行时间相等

小于情况

大于情况

如果本地时间相差较大 多同步几次

IEEE 1588
NTP PTP and so on
--------游戏行业用这些东西 就和做纳秒级别的sleep一样 纯忽悠

Thank you for your sharing

Thank you for your sharing

NTP 貌似就是第三方

好难看懂啊,继续看。

可否服务器发送时间到桌面,桌面把本机时间也发送到服务器。
连续发两次。
这样桌面可以得到一去一回的时间和,一来一去又一来的时间和,这样得到两个方程,两个未知数,可解。

先留言在看看

应该是想复杂了.游戏中的时间同步还是应该走多次采样取平均延迟时间来得较为简单和可靠.峰值误差或极端的上下行如果真是频繁发生,那么涉及到的问题太多,玩家基本也不可能有什么好的游戏体验,申请更好的接入商或许是更直接的办法.

晕,果然是用TC,不好意思阿,刚才没仔细看:(

问个题外话,是用netem/tc来模拟的延迟吗?还是用的其他的工具?

谢谢

IEEE 1588
NTP PTP and so on

中文的句号在我的chrome浏览器上看,显示不完整,只有下半圈的。当看到“C D E 。A”时,以为是个数学符号...

嗯,现在看不懂,不过以后应该会看的懂的,加油!

沙发。

Post a comment

非这个主题相关的留言请到:留言本