计算机之间怎么对时?NTP 用一对请求和应答里的四个时间戳算出本地时钟的偏移和网络延迟。这篇手工发 NTP 请求给真实服务器,逐字段解析,验证偏移公式,并用一个自己写的服务器证明路径不对称会让对时出现不可消除的误差。
请求 48 字节,首字节 0x23 = LI 0 | 版本 4 | 模式 3(客户端);只有 transmit 时间戳(最后 8 字节)有值;应答 48 字节,来自 203.107.6.88
应答头:LI=0(0=正常),版本 4,模式 4(4=服务器),stratum 3,poll 0(2^0 秒),precision -25(2^-25 秒 ≈ 30 ns)
根延迟 root delay 10.60 ms,根离散度 root dispersion 10.19 ms,参考标识 100.107.25.114(stratum ≥ 2 时是上游服务器的 IPv4 地址,stratum 1 时是 4 字符的时钟源名如 GPS)
四个时间戳(都是 64 位:32 位整数秒 + 32 位小数,起点 1900-01-01):
T1 originate(我发出请求的时刻,被服务器原样抄回)= 1792062857.327713,与我记录的 T1 1792062857.327713 差 0.00 µs(32 位小数的精度 ≈ 0.23 ns,但是 Python float 只有微秒量级)
T2 receive(服务器收到)= 1792062857.344211;T3 transmit(服务器发出)= 1792062857.345903;T4(我收到)= 1792062857.352936
服务器的处理时间 T3 − T2 = 1692.5 µs;往返时间 T4 − T1 = 25.22 ms
偏移 offset = ((T2 − T1) + (T3 − T4)) ÷ 2 = 4.73 ms;延迟 delay = (T4 − T1) − (T3 − T2) = 23.53 ms48 字节:头部(LI、版本、模式、stratum 等)加四个 64 位时间戳。
服务器 stratum 参考标识 偏移中位(ms) 偏移范围(ms) 延迟中位(ms) 延迟范围(ms)
ntp.aliyun.com 3 100.107.25.114 1.59 [ -1.00, 4.59] 19.93 [19.02, 22.69]
ntp.tencent.com 2 100.122.36.196 -1.56 [ -11.31, 5.63] 52.51 [46.47, 71.86]
time.cloudflare.com 3 10.191.8.4 6.75 [ -6.76, 11.10] 173.51 [163.90, 179.46]
pool.ntp.org 3 10.127.8.21 5.40 [ 2.64, 13.20] 175.30 [157.16, 186.56]
各服务器给出的偏移中位数 [1.6, -1.6, 6.7, 5.4] ms:它们互相一致(差 8.3 ms)说明本机时钟相对标准时间的偏移就是这个量级;单次测量的抖动(范围)远大于偏移的真值误差,所以 NTP 客户端要多次采样、取延迟最小的那一次offset = ((T2−T1)+(T3−T4))÷2,delay = (T4−T1)−(T3−T2)。真实服务器延迟 20~175 ms,偏移 −1.6~6.7 ms。
对称往返(每方向 50 ms):offset 中位 250.09 ms(服务器拨快了 250 ms;本机相对服务器慢 → offset 为 +250);delay 中位 101.31 ms(≈ 2 × 50 ms) 误差:offset 与真值 250 ms 之差 0.09 ms
对称路径下,250 ms 的时钟差被测到 250.09 ms。
返程多 80 ms 后:offset 中位 208.02 ms(真值仍是 +250 ms);delay 中位 184.53 ms offset 的误差 = -41.98 ms,恰好是不对称量 80 ms 的一半的相反数(-40 ms):NTP 把整个往返时间平分给两个方向,所以它测不出也修正不了不对称——这是网络对时精度的根本限制
NTP 把往返平分,不对称的一半会变成偏移误差(−41.98 ms)。