NTPPC佳生(NTPPC是什么)

戳我有惊喜!!!

一、NTP协议简介

NTP网络时间协议是TCP/IP协议族里的一个应用层协议,常用于客户端与服务器进行时钟同步,提供高精度的时间校准,由于该服务存在并发量大且对丢包也没有要求,所以传输层一般使用UDP报文,而TCP存在确认、重传、阻塞等机制导致传输速率也不如UDP,一般情况系统默认使用123端口作为NTP端口。

NTP服务可用于网络管理、计费系统、银行授时、协同处理、系统时间、安全认证等场景,这些场景一般对时间精度有较高的要求,比如心知天气使用私钥加公钥,为了私钥安全还引入时间戳有效判断机制,通过时间戳约束公钥有效期,不知心知天气API采用这种通讯机制,很多的网络通讯为了安全都会对系统时间进行校验,因此有一个统一的标准时间对于网络而言意义重大。

NTP就是用来同步网络中各个主机时钟的一种协议,他将全球各大授时中心的准确时间分享给设备,其精度在内网内可达1毫秒内,在互联网上可以达到几十毫秒以内。

分享一些国内常用的NTP服务器:

中国科学院国家授时中心(ntp.ntsc.ac.cn:123)腾讯云NTP授时服务(ntp.tencent.com:123)阿里云NTP授时服务(ntp.aliyun.com:123)教育网NTP授时服务(time.edu.cn:123)

二、实例分析

NTP报文

部分HMI本身没有对NTP服务进行集成,应该必须对NTP报文有一定的了解才能正确使用NTP对时服务器,下面将通过分析NTPv3了解NTP报文格式。

下面是一个发送实例,注意远程主机必须使用域名,我这里实际使用的是ntp.ntsc.ac.cn:123,软件在发送后自动DNS并覆盖了我的输入,重要的事说三遍,必须使用域名!!!必须使用域名!!!

这里将发送时间和内容都进行记录,也对NTP服务器返回时间与数据进行记录,后面分析应当配置的准确会用到日志和数据收到的时间。

[2022-08-12 11:47:50.805]# SEND HEX TO 114.118.7.163 :123>

1B 00 04 FA 00 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

[2022-08-12 11:47:50.853]# RECV HEX FROM 114.118.7.163 :123>

1C 02 04 EA 00 00 05 CF 00 00 15 6C 7B 8B 21 03 E6 A0 44 42 42 72 91 0E 00 00 00 00 00 00 00 00 E6 A0 4B E8 11 B7 C8 3E E6 A0 4B E8 11 B8 9C 4D

这里统计计算时间的方法,NTP报文中使用的是时间戳机制,我们将发送时间2022-08-12 11:47:50.805与接收时间2022-08-12 11:47:50.853也转换为时间戳方便后续使用,通过网上搜索的时间戳转换工具精选转换发送时间(1660276070)与接收时间(1660276070)。

这篇文章不对协议进行分析仅对部分位进行说明。

NTP报文使用长度为64 Bits无符号数存储一个时间戳,前32 Bits表示整数部分, 后32 Bits表示小数部分, 理论分辨率 2^−32s,由于HMI精度只能到秒,小数位对于本项目是没有任何用处,不再分析小数部分,将接收报文记录离开NTP服务的时间戳从报文中分离(E6 A0 4B E8 11 B8 9C 4D),提取前四个字节(HEX:E6 A0 4B E8DEC:3869264872),与发送日志的1660276070805相差甚远,这里就是NTP报文最坑的地方,时间戳0表示的是1970-01-01 08:00:00开始计算,而NTP服务的时间戳是从1900-01-01 00:00:00开始计算,因此两种时间戳需要通过减去一个系数才能转换2208988800= (70 * 365 + 17) * 24 * 60 * 60。

服务器返回的时间戳(3869264872-2208988800=1660276072),可见设备发送日志与实际时间相差2s。

实际上NTP对时服务在计算精确时间是有一个推荐公式,

客户端与服务端的时间系统的偏移定义为θ、网络的往返延迟定义为δ,基于此,可以对t2进行精确的修正,已达到相关精度要求,它们的计算公式如下:

式中:

t0是请求数据包传输的客户端时间戳

t1是请求数据包回复的服务器时间戳

t2是响应数据包传输的服务器时间戳

t3是响应数据包回复的客户端时间戳

实际写入的时间为t2加上网络延时δ的一半就可以了(t2+δ/2)。

移植到HMI

经过上面原理的学习,对NTP有了一定的了解,现在根据HMI的要求将业务流程复制到脚本中实现。

新建变量,使用透传的模式的设备驱动,主要是学习脚本,以前关于MQTT协议的文章有讲过怎样配置驱动,变量表如下图,由于NTP协议使用16进制收发数据,也就需要对应调整收发数据模式:

使用按键关联发送脚本如下:

COM1_WRITE_BUFF_CACHE="1B0004FA0001000000010000000000000000000000000000000000000000000000000000000000000000000000000000"

!SetDevice(system_time,6,"Write(COM1_WRITE_BUFF_CACHE, COM1_READ_BUFF_CACHE)")

t0=!TimeGetCurrentTime()

使用事件策略关联接收状态变量“COM1_READ_RUN_STATE”,在电平跳变时触发“数据解析”与“时间配置”脚本:

“数据解析”,将NTP服务返回的数据保存到t1_str与t2_str,在转换成时间戳存储在t1与t2,

IF !len(COM1_READ_BUFF_CACHE)=96 THEN

t3=!TimeGetCurrentTime()

t1_str=!mid(COM1_READ_BUFF_CACHE,65,8)

t1=!Hex2I(t1_str)-2208988800

t2_str=!mid(COM1_READ_BUFF_CACHE,80,8)

t2=!Hex2I(t2_str)-2208988800

set_time=t2+((t3-t0)-(t1-t1))/2

ENDIF

“时间配置”,利用计算得到的时间戳配置HMI系统时间:

!SetTime(!TimeGetYear(set_time),!TimeGetMonth(set_time),!TimeGetDay(set_time),!TimeGetHour(set_time),!TimeGetMinute(set_time),!TimeGetSecond(set_time))