SNTP简介

要了解SNTP,首先需要了解NTP协议。SNTP是NTP的子集,简化了NTP的许多算法和步骤,得到了效率,但时间的精度不如NTP,可是对于民用时间来说足够了,大概最多差距几秒的样子。

 

NTP(Network Time Protocol,网络时间协议)是由RFC 1305定义的时间同步协议,用来在分布式时间服务器和客户端之间进行时间同步。NTP基于UDP报文进行传输,使用的UDP端口号为123。

 

使用NTP的目的是对网络内所有具有时钟的设备进行时钟同步,使网络内所有设备的时钟保持一致,从而使设备能够提供基于统一时间的多种应用。

 

对于运行NTP的本地系统,既可以接收来自其他时钟源的同步,又可以作为时钟源同步其他的时钟,并且可以和其他设备互相同步。

 

NTP工作原理

NTP的基本工作原理如图所示。Device A和Device B通过网络相连,它们都有自己独立的系统时钟,需要通过NTP实现各自系统时钟的自动同步。为便于理解,作如下假设:

在Device A和Device B的系统时钟同步之前,Device A的时钟设定为10:00:00am,Device B的时钟设定为11:00:00am。

Device B作为NTP时间服务器,即Device A将使自己的时钟与Device B的时钟同步。

   NTP报文在Device A和Device B之间单向传输所需要的时间为1秒。

       系统时钟同步的工作过程如下:

   Device A发送一个NTP报文给Device B,该报文带有它离开Device A时的时间戳,该时间戳为10:00:00am(T1)。

   当此NTP报文到达Device B时,Device B加上自己的时间戳,该时间戳为11:00:01am(T2)。

  当此NTP报文离开Device B时,Device B再加上自己的时间戳,该时间戳为11:00:02am(T3)。

  当Device A接收到该响应报文时,Device A的本地时间为10:00:03am(T4)。

至此,Device A已经拥有足够的信息来计算两个重要的参数:

  NTP报文的往返时延Delay=(T4-T1)-(T3-T2)=2秒。

  Device A相对Device B的时间差offset=((T2-T1)+(T3-T4))/2=1小时。

这样,Device A就能够根据这些信息来设定自己的时钟,使之与Device B的时钟同步。

 

NTP时间戳

NTP时间戳是该协议的重要产品,用来对时间进行精确表示。它由一个64位无符号浮点数组成,整数部分为头32位,小数部分为后32位;单位为秒,时间相对于19001月零点。它能表示的最大数字为4294967295秒,同时具有232PS的精确性,这能满足最苛刻的时间要求。值得注意的是在1968年的某一个时间(2147483648秒)时间戳的最高位已被设置为1,在2036年的某一个时间(4294967295秒)64位字段将会溢出,所有位将会被置为零,此时的时间戳将会被视为无效。为了解决这一问题,尽量延长SNTP时间戳的使用时间,一种可能的办法为:如果最高位设置为1UTC时间范围为1968-2036之间,时间计算起点从19001000秒开始计算;如果最高位设置为0UTC时间范围为2036-2104之间,时间计算起点从20362762816秒开始计算;

 

NTP的报文格式

NTP有两种不同类型的报文,一种是时钟同步报文,另一种是控制报文。控制报文仅用于需要网络管理的场合,它对于时钟同步功能来说并不是必需的,这里不做介绍。

 

主要字段的解释如下:

l  LI:当前时间闰秒标志。字段长度为2位整数,只在服务器端有效。取值定义为:

LI=0:无警告;

LI=1:最后一分钟是61秒;

LI=2:最后一分钟是59秒;

LI=3:警告(时钟没有同步)

服务器在开始时,LI设置为3,一旦与主钟取得同步后就设置成其它值。

 

l  VN(Version Number):长度为3比特,表示NTP的版本号,可以是3或者是4

Mode:指示协议模式。字段长度为3位,取值定义为:

Mode=0:保留

Mode=1:对称主动;

Mode=2:对称被动;

Mode=3:客户;

Mode=4:服务器;

Mode=5:广播;

Mode=6:保留为NTP控制信息;

Mode=7:保留为用户定义;

在单播和多播模式,客户在请求时把这个字段设置为3,服务器在响应时把这个字段设置为4。在广播模式下,服务器把这个字段设置为5

 

l  Poll Interval:指示数据包的最大时间间隔,以秒为单位,作为2的指数方的指数部分,该字段只在服务器端有效。字段长度为8位整数,取值范围从4-17,即16秒到131,072秒。

 

l  Precision:指示系统时钟的精确性,以秒为单位,作为2的指数方的指数部分,该字段只在服务器端有效。字段长度为8位符号整数,取值范围从-6-20

 

l  Root Delay:指示与主时钟参考源的总共往返延迟,以秒为单位,该字段只在服务器端有效。字段长度为32位浮点数,小数部分在16位以后,取值范围从负几毫秒到正几百毫秒。

 

l  Root Dispersion:指示与主时钟参考源的误差,以秒为单位,该字段只在服务器端有效。字段长度为32位浮点数,小数部分在16位以后,取值范围从零毫秒到正几百毫秒。

 

l  Reference Identifier:指示时钟参考源的标记,该字段只在服务器端有效。对于一级服务器,字段长度为4字节ASCII字符串,左对齐不足添零。对于二级服务器,在IPV4环境下,取值为一级服务器的IP地址,在IPV6环境下,是一级服务器的NSAP地址。

 

l  Reference Timestamp:指示系统时钟最后一次校准的时间,该字段只在服务器端有效,以前面所述64位时间戳格式表示。

 

l  Originate Timestamp:指示客户向服务器发起请求的时间,以前面所述64位时间戳格式表示。

l  Receive Timestamp:指服务器收到客户请求的时间 ,以前面所述64位时间戳格式表示。

 

l  Transmit Timestamp:指示服务器向客户发时间戳的时间,以前面所述64位时间戳格式表示。

l  Authenticator(可选):当需要进行SNTP认证时,该字段包含密钥和信息加密码

 

国内可用的NTP Server

1.cn.pool.ntp.org

2.cn.pool.ntp.org

3.cn.pool.ntp.org

0.cn.pool.ntp.org

cn.pool.ntp.org

tw.pool.ntp.org

0.tw.pool.ntp.org

1.tw.pool.ntp.org

2.tw.pool.ntp.org

3.tw.pool.ntp.org


这十台服务器从地理位置上说离我们最近,它们所提供给我们的时间与标准时间之间的差别也最小,在国内使用,精度完全够用!


用python实现sntp客户端

#coding=utf-8
import socket
import struct
import sys
import time

NTP_SERVER = '2.cn.pool.ntp.org'
#1970年的NTP时间戳
TIME1970 =2208988800L

def sntp_client():
    client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    
    
    #客户端主要构造前三个字段即可,后面所有位都填充0
    #'\x23' 展开为 00 100 011 分别填充LI, VN, Mode字段
    #余下的47 * 8 = 376位都填充0
    data = '\x23' + 47 * '\0'  
    client.sendto(data, (NTP_SERVER, 123))
    data, address = client.recvfrom(1024)
    if data:
        print 'Response received from:', address
    
    #得到Transmit Timestamp:即服务器向客户发时间戳的时间 
    t = struct.unpack( '!12I', data)[10]
    
    #减去1970年的NTP时间,得到Unix时间戳
    t -= TIME1970
    print '\tTime=%s' % time.ctime(t)

if __name__ == '__main__':
    sntp_client()

 

1970年的NTP时间戳获得

不同的时间戳只不过是相对的时间点不同,NTP时间戳是距1900年1月1日0点0分0秒的秒数,而Unix时间戳是距1970年1月1日0点0分0秒的秒数。我们想知道1970年的NTP时间戳,实际上是1970年和1900年之间的秒数。而这个数字也等于 abs(1900年的Unix时间戳)。

所以我们可以利用在线Unix时间戳转换工具算出这个值。取正之后,就是1970年的NTP时间戳。

本来想用Python算出这个值,可是python的mktime函数不支持1970年以前的时间。

不知道有没有其它的函数可以算出,等以后遇到后可以再补充。


  • 3
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: ESP8266是一种低成本、高性能的Wi-Fi芯片,广泛应用于物联网(IoT)领域。SNTP(Simple Network Time Protocol)是一种基于UDP协议的时间同步协议,在物联网设备中具有重要的应用价值。 ESP8266通过SNTP协议与互联网中的时间服务器通信,获得准确的时间戳。这些时间戳可用于日志记录、事件触发、时间截止等应用场景。 SNTP协议本身非常简单,可以使用ESP8266的标准库集成到程序中。通过WiFi连接到局域网或互联网后,ESP8266可以与指定的时间服务器同步,获取与本地时间的时间差。为了准确,ES8266通常使用多个时间服务器进行同步,并进行平均计算。 值得注意的是,SNTP协议是基于UDP协议的,因此无法保证在传输过程中的可靠性。为了解决这个问题,ESP8266通常会定期进行时间同步,以保证时间准确性。当然,若是在时间同步失败的情况下采用短时间运行,错误也会相应地累积。因此,一些特殊的应用场景需要采用GPS等时间同步手段来确保时间的准确性。 总之,ESP8266通过SNTP协议可以快速、准确地获取互联网上的时间戳,因此在物联网设备的时间同步方面拥有巨大的应用潜力。 ### 回答2: ESP8266是一款低成本的Wi-Fi芯片,可以方便的接入互联网。SNTP(Simple Network Time Protocol)是一种简单的网络时间协议,用于同步网络设备的时间。 在ESP8266中,可以使用SNTP协议来同步设备的时间。通过连接SNTP服务器,ESP8266可以获取世界标准时间,并将其与本地时间进行比较和更新。这非常有用,因为设备的时间通常需要与其他设备同步,以便它们可以协调它们的操作。 ESP8266支持SNTP协议的库如下: • sntp.h • sntp.c 这些库可以在ESP8266的开发环境中进行安装和使用。使用这些库,可以轻松地与SNTP服务进行通信,以便同步设备的时间。在使用这些库时,用户需要提供SNTP服务器的IP地址和端口号。然后,ESP8266会连接到服务器并获取当前的时间。 SNTP协议的一个重要特点是具有低带宽和延迟。这使得设备可以在非常低的成本和能耗下同步时间。由于ESP8266的能源需求非常低,因此使用SNTP协议进行时间同步是非常有效的方法。这使得ESP8266成为物联网设备设计的首选芯片之一。 ### 回答3: ESP8266是一款高性能、低功耗、易于开发的Wi-Fi芯片,可以通过SNTP协议进行时间同步。SNTP(Simple Network Time Protocol)是NTP协议的简化版本,用于进行网络时间同步。 在ESP8266上使用SNTP进行时间同步,需要先通过WiFi连接到网络。然后,使用SNTP协议向NTP服务器请求时间信息,并将服务器返回的时间设定为ESP8266的系统时间。这个过程可以使用ESP8266自带的API实现,也可以使用第三方库完成。 使用SNTP同步时间有很多好处,其中最主要的就是可以保证设备时间的准确性。在一些需要高精度时间的应用场景,比如金融、物流等领域,时间同步显得尤为关键。 总之,ESP8266虽然是一款小巧的芯片,但它拥有丰富的功能和强大的性能,可以为各种物联网应用提供稳定可靠的支持。SNTP协议则是保证ESP8266时间准确性的重要手段之一。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值