Time-1-NTP协议
电脑的时钟
你肯定注意到,假如电脑隔了几天没有打开,任务栏的时间依然是正确的,即使你的电脑没有联网,这是如何做到的?
计算机的主板上有一个石英晶体振荡器和一个纽扣电池,通过纽扣电池为石英晶体振荡器与集成电路提供能量,从而稳定产生32768HZ的振荡频率,经过集成电路进行16级分频和整形,最终输出周期为2S的对称方波,那么半个周期为1S。
经验表示,振荡器的频率越高,抗干扰能力越强。普通石英晶体振荡器的每日误差小于0.5秒。但在极端温度下,比如零下二十度,误差会变大。
NTP协议架构
由于石英晶体误差比较大,所以1985年特拉华大学David L.Mills设计了网络时间协议NTP(Network Time Protocol)来同步不同计算机系统之间的时钟。
NTP时钟的目标是将所有计算机的时间同步到几毫秒误差内。实际上广域网可以达到几十毫秒的误差,局域网误差可以在1毫秒内。NTP协议是一种主从式架构协议,使用分层的时钟源系统,每一层称为Stratum。阶层的上限是15,阶层16表示未同步设备。

- 阶层0:参考基准时钟,主要由高精度计时设备,比如铯或铷原子钟、GPS时钟、无线电时钟。它们生成非常精确的脉冲信号,触发计算机上的中断和时间戳。
- 阶层1:主时间服务器,这些服务器与阶层0设备相连,在几微秒误差内同步系统时钟。阶层1服务器之间可以相互连接,进行完整性检查和备份。
- 阶层2:这些计算机通过网络和阶层1服务器同步。每个计算机可以查询多个阶层1服务器,阶层2计算机之间也可以互相连接。
- 阶层3:这些计算机与阶层2的服务器同步。
NTP协议流程
NTP协议的时钟同步过程如下:

- 客户端A发送NTP消息给服务器B,消息中包含发送时间戳T1;
- 服务器B收到NTP消息后,将接收时间T2写入消息中;
- 服务器B发送该NTP消息给客户端A,发送消息T3写入消息中;
- 客户端A收到该NTP消息的时间为T4。
从上面的流程中可以很容易计算出:
AB之间的网络往返时间RTT(Round Trip Time):δ = (T4 - T1) - (T3 - T2)
假设AB之间的时间偏差为θ,那么T3 - θ = T3’
T4和T3’的间隔是半个RTT:T4 - T3’ = δ / 2
联立以上三式得到:θ = T3 - T3’ = T3 - [(T4 - T1) - (T3 - T2)] / 2 = [(T2 - T1) + (T3 - T4)] / 2
NTP协议格式
NTP协议使用UDP协议来传输,端口为123,报文格式如下:
1 | 0 1 2 3 |
各个字段的含义如下:
- LI Leap Indicator:2bit,用来警告是否有闰秒或者未和上级同步。具体定义如下:
1 | +-------+----------------------------------------+ |
- VN Version Number:3bit,协议版本,目前是4。
- Mode:3bit,工作模式,具体定义如下:
1 | +-------+--------------------------+ |
- Stratum:8bit,阶层,具体定义如下:
1 | +--------+-----------------------------------------------------+ |
- Poll:8比特,轮询间隔时间,两个NTP报文之间的时间间隔,用2的幂表示。
- Precision:8比特,系统的时钟精度,用2的幂表示。
- Root Delay:32比特,本地到主时钟源的往返时间RTT。
- Root Dispersion:32比特。
- Reference Identifier:32比特,上层时钟源的标识。
- Reference Timestamp:64比特,本系统时钟最后一次被设置的时间。
- Originate Timestamp:64比特,NTP报文离开发送端时发送端本地时间,也即前面图中的T1。
- Receive Timestamp:64比特,NTP报文到达接收端时接收端端本地时间,也即前面图中的T2。
- Transmit Timestamp:64比特,NTP报文离开接收端时接收端本地时间,也即前面图中的T3。
NTP的误差
NTP协议在广域网可以达到几十毫秒的误差,局域网误差可以在1毫秒内。误差最大的一个原因是发送请求和接受相应这两个阶段的网络时间可能是不一样的。前面我们推到偏移公式的时候,假设网络往返发送和接收阶段的时间是一样的,但是在实际网络中,这两个阶段走的路由可能是不一样的,所花的时间也可能不一样,计算的时间便宜也不准确,这样就造成了广域网的误差可能达到几十毫秒甚至更高。局域网中因为网络比较稳定,经过的路由器也比较少,所以误差可以到1毫秒内。
参考文献
[1] rfc5905
[2] NTP 协议简单分析