NTP协议入门介绍
NTP入门介绍
这篇文章除了代码部分,其他均为我从其他人文章处搬运过来的,只阐述我个人的阅读思路,读者如果看到写的不好的地方敬请谅解,可以从文章底部原文跳转查看!
概述
网络时间协议,英文名称:Network Time Protocol(NTP) 是用来使计算机时间同步化的一种协议,它可以使计算机对其服务器或时钟源(如石英钟,GPS等等)做同步化,
它可以提供高精准度的时间校正(LAN上与标准间差小于1毫秒,WAN上几十毫秒), 且可介由加密确认的方式来防止恶毒的协议攻击。NTP的目的是在无序的Internet环境中提供精确和健壮的时间服务。NTP 基于 UDP 报文进行传输, 使用的UDP端口号为 123.
使用 NTP 的目的是对网络内所有具有时钟的设备进行时钟同步, 使网络内所有设备的时钟保持一致, 从而使设备能够提供基于统一时间的多种应用.
对于运行 NTP 的本地系统, 既可以接收来自其他时钟源的同步, 又可以作为时钟源同步其他的时钟, 并且可以和其他设备相互同步.
工作原理
实现方式
- 无线时钟: 服务器系统可以通过串口连接一个无线时钟. 无线时钟接收 GPS 的卫星发射的信号来决定当前时间. 无线时钟是一个非常精确的时间源, 但是需要花一定的费用.
- 时间服务器: 还可以使用网络中 NTP 时间服务器, 通过这个服务器来同步网络中的系统的时钟.
- 域网内的同步: 如果只是需要在本局域网内进行系统间的时钟同步, 那么就可以使用局域网中任何一个系统的时钟. 你需要选择局域网中的一个节点的时钟作”权威的”的时间源, 然后其它的节点就只需要与这个时间源进行时间同步即可. 使用这种方式,
所有的节点都会使用一个公共的系统时钟, 但是不需要和局域网外的系统进行时钟同步. 如果一个系统在一个局域网的内部, 同时又不能使用无线时钟, 这种方式是最好的选择.
工作流程
- 这里目前我只列举【NTP服务端与客户端的交互过程】这一工作模式,还有许多其他的工作模式, 请参考这边文章,东西写的是真的详细,我的基本都是从这里搬运过来的.
NTP 协议简单分析
NTP服务端与客户端的交互过程
客户端和服务端都有一个时间轴,分别代表着各自系统的时间,当客户端想要同步服务端的时间时,客户端会构造一个NTP协议包发送到NTP服务端,客户端会记下此时发送的时间t0,经过一段网络延时传输后,服务器在t1时刻收到数据包,经过一段时间处理后在t2时刻向客户端返回数据包,
再经过一段网络延时传输后客户端在t3时刻收到NTP服务器数据包。
t0和t3是客户端时间系统的时间、t1和t2是NTP服务端时间系统的时间,它们是有区别的。 t0、t1、t2分别对应着server->cient NTP报文中的三个参数:
t0:origin timestamp(客户端发送数据包的时间)
t1: receive timestamp(服务器接收到数据包的时间)
t2: transmit timestamp(服务器返回数据包时间)
t3: client receive timestamp(客户端收到回复报文时本地的时间)。
延时和时间偏差计算
假设:客户端与服务端的时间系统的偏差定义为θ
、网络的往/返延迟(单程延时)定义为δ
。
推导过程:
- 根据交互原理,可以列出方程组:
1 | t0+θ+δ=t1 |
- 求解方程组,得到以下结果:
1 | θ=(t1-t0+t2-t3)/2 |
记忆时可以采用极限法,分别假设延时和偏差为0.
客户端时间校准
对于时间要求不那么精准设备,客户端可把服务端端的返回时间t2固化为本地时间。
但是作为一个标准的通信协议,必须计算上网络的传输延时,需要把t2+δ
固化为本地时间。
以上client时间校准算法只为理解过程,不代表真实做法
NTP报文
NTP报文示例
其中192.10.10.189为NTP的server端,192.10.10.32为client端。
NTP报文格式
- NTP 有两种不同类型的报文, 一种是 时钟同步报文, 一种是 控制报文.
- 控制报文 仅用于需要网络管理的场合, 对于时钟同步功能不是必需的, 暂不做分析.
- 时钟同步报文格式如下:
NTP报文格式如上图所示,它的字段含义参考如下:
- LI (Leap Indicator): 闰秒标识器, 长度为 2 Bits, 用来预警最近一分钟插入 1s 或者删除 1s.
LI | Value | 含义 |
---|---|---|
00 | 0 | 无预告 |
01 | 1 | 醉经一分钟有 61s |
10 | 2 | 最近一分钟有 59s |
11 | 3 | 警告状态(时钟未同步) |
- VN (Version Number): 版本号, 长度为 3 Bits, 目前最新的版本是 4, 向下兼容指定于 RFC 1305 的版本 3.
- Mode: 工作模式, 长度为 3 Bits.
点对点模式下, 客户端请求时设置此字段为 3, 服务器应答时设置此字段为 4. 广播模式下, 服务器应答设置此字段为 5.
Mode | Value | 含义 |
---|---|---|
000 | 0 | 保留 |
001 | 1 | 主动对称模式 |
010 | 2 | 被动对称模式 |
011 | 3 | 客户端模式 |
100 | 4 | 服务器模式 |
101 | 5 | 广播或组播模式 |
110 | 6 | NTP控制报文 |
111 | 7 | 预留给内部使用 |
- Stratum: 系统时钟的层数, 长度为 8 Bits, 取值范围 1~16, 定义时钟的准确度. 层数为 1 的时钟准确度最高, 准确度从 1 到 16 依次递减, 阶层的上限为15, 层数为 16的时钟处于未同步状态,
不能作为参考时钟.- NTP 获得 UTC 的时间来源可以是原子钟, 天文台, 卫星, 也可以从Internet上获取.
- stratum-0 是高精度计时设备, 例如原子钟 (如铯, 铷), GPS时钟或其他无线电时钟. 它们生成非常精确的脉冲秒信号, 触发所连接计算机上的中断和时间戳. 也称为参考 (基准) 时钟.
- stratum-1 是与 stratum-0 设备相连, 在几微秒误差内同步系统时钟的计算机.
- 时间是按 NTP 服务器的等级传播. 按照距离外部 UTC 源的远近将所有服务器归入不同的 Stratum (层) 中. Stratum-1 在顶层, 有外部 UTC 接入, 而Stratum-2 则从 Stratum-1
获取时间, Stratum-3 从 Stratum-2 获取时间, 以此类推, 但 Stratum 层的总数限制在15以内. 所有这些服务器在逻辑上形成阶梯式的架构并相互连接, 而 Stratum-1
的时间服务器是整个系统的基础.
stratum | 含义 |
---|---|
0 | 未指定或者难以获得 |
1 | 主要参考(如: 无线电时钟,校正的原子时钟) |
2~15 | 第二参考(Via NTP) |
16 | 未同步状态, 不能作为参考时钟 |
- Poll: 轮询间隔时间, 长度为 8 Bits, 两个连续NTP报文之间的时间间隔, 用 2 的幂来表示, 比如值为 6 表示最小间隔为 2^6 = 64s.
- Precision: 系统时钟的精度, 长度为 8 Bits, 用 2 的幂来表示, 比如 50Hz(20ms)或者60Hz(16.67ms) 可以表示成值 -5 (2^-5 = 0.03125s = 31.25ms).
- Root Delay: 本地到主参考时钟源的往返时间, 长度为 32 Bits, 有 15~16 位小数部分的无符号定点小数.
- Root Dispersion: 系统时钟相对于主参考时钟的最大误差, 长度为 32 Bits, 有 15~16 位小数部分的无符号定点小数.
- Reference Identifier: 参考时钟源的标识, 长度为 32 Bits.
- Reference Timestamp: 系统时钟最后一次被设定或更新的时间, 长度为 64 Bits, 无符号定点数, 前 32 Bits 表示整数部分, 后 32 Bits 表示小数部分, 理论分辨率 2^−32s.
- Originate Timestamp: NTP请求报文离开发送端时发送端的本地时间, 长度为 64 Bits.
- Receive Timestamp: NTP请求报文到达接收端时接收端的本地时间, 长度为 64 Bits.
- Transmit Timestamp: 应答报文离开应答者时应答者的本地时间, 长度为 64 Bits.
- Authenticator(Optional): 验证信息, 长度为 96 Bits, (可选信息), 当实现了 NTP 认证模式时, 主要标识符和信息数字域就包括已定义的信息认证代码 (MAC) 信息.
说明
(这里是最容易被坑到的) 时间戳的记录以秒的形式从 1900-01-01 00:00:00 算起. NTP的时间精度在 WAN 为 数十毫秒, 在 LAN 为 亚毫秒级甚至更高, 在 Internet 上绝大部分能提供 1-50ms 的精确度, 取决于同步源和网络路径等特性. 比如: 当前时间为 1902-01-01 01:01:01, 与 1900 的参考时间相差为:
(3652246060+3600+60+1) = 63075661s = 0x03C2754D s. 转换成二进制: 0000 0011 1100 0010 0111 0101 0100 1101 XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX. 因为只有 32 Bits 表示秒数, 所以到了 2036 年数据就会溢出. 所以以 136 年为一个周期置 0 , 会用一些外部的方法来表示是相对于 1900 年还是 2036 年的时间. NTP 的未来版本可能将时间表示扩展到 128 Bits: 其中 64 Bits 表示秒, 64 Bits 表示秒的小数. 当前的 NTPv4 格式支持 “时代数字” (Era Number)和 “时代偏移” (Era Offset), 正确使用它们应该有助于解决日期翻转问题. 据Mills称: “64 Bits 秒的小数足以分辨光子以光速通过电子所需的时间. 64 Bits 的秒足以提供明确的时间表示, 直到宇宙变暗.”
java代码实现
这里的实现方式其实是有很多种,且并非java代码来实现的,但是由于我比较擅长java语言,所以这里就以java语言为示例来展示ntp的实现逻辑
1 |
|
参考文章
一开始看了很多篇都大差不差的文章,总是没办法完整的理解ntp协议的含义,后面google到一篇发现讲的非常的好,这里我不得不吐槽baidu这个垃圾了,同样的关键字google确实能查到更优质的内容。
特别感谢这篇
下面这些也很重要