全网源设备精准时间同步服务-方案:gps精准授时-ntp时间服务

嵌入式NTP时间同步机制技术积累

                                                                             北京华环.开发部:任晓亮 2015/11/27

项目:*******

硬件平台:NIOS2

源码:OpenSource NTP

源码网址:http://www.ntp.org/downloads.html

源码版本: ntp-4.2.6p4.tar.gz

一:编译

解压:tar –zxvf ntp-4.2.6p4.tar.gz

配置:

./configure  --host=nios2-linux

--prefix=$HOME/work/nios-kernel/software_cross/ntp-4.2.6p4/_install

(--prefix=$PWD/_install)

注意配置前在建立:mkdir _install

编译:

makeCC=nios2-linux-gnu-gcc

安装:make install

二:使用

2.环境搭建好的话,可以顺利编译过

安装目录:

renxl@icserver:~/work/nios-kernel/software_cross/ntp-4.2.6p4/_install/nios2$ls

bin  lib sbin  share

renxl@icserver:~/work/nios-kernel/software_cross/ntp-4.2.6p4/_install/nios2/bin$ls

ntpd  ntpdate ntpdc  ntp-keygen  ntpq ntptime  ntptrace  ntp-wait sntp  tickadj

服务器段程序:ntpd

服务器配置文件:/etc/ntp.conf

启动方法:ntpd –g –u –p/var/ntp.pid

客户端程序:ntpdate

启动方法:ntpdate –dserver-addr

定时同步用crontab
# crontab -e

crontab: chdir(/var/spool/cron/crontabs): Nosuch file or directory
出现上面情况则执行
# mkdir -p /var/spool/cron/crontabs

三:问题

参考材料:

http://blog.chinaunix.net/uid-20680966-id-4243556.html

问题1:

编译出错:提示gcc 不支持参数"Wstrict-overflow"

解决:在源码根目录下查找这个参数,将这几个文件中的这个参数去掉,主要是configure.ac

Configure文件,(注意在执行查找的事先make distclean清理一下源码

renxl@icserver:~/work/nios-kernel/software_cross/ntp-4.2.6p4$grep -r -n "Wstrict-overflow"

configure.ac:148:    CFLAGS="$CFLAGS-Wstrict-overflow"

configure.ac:150:    [if $CC can handle -Wstrict-overflow],

configure.ac:279:    CFLAGS="$CFLAGS -Wstrict-overflow"

configure:7702:    CFLAGS="$CFLAGS-Wstrict-overflow"

configure:7703:    { $as_echo"$as_me:${as_lineno-$LINENO}: checking if $CC can handle-Wstrict-overflow" >&5

configure:7704:$as_echo_n "checking if$CC can handle -Wstrict-overflow... " >&6; }

configure:7968:        CFLAGS="$CFLAGS -Wstrict-overflow"

sntp/configure.ac:81:    CFLAGS="$CFLAGS-Wstrict-overflow"

sntp/configure.ac:83:      [if $CC can handle -Wstrict-overflow],

sntp/configure.ac:170:    CFLAGS="$CFLAGS -Wstrict-overflow"

sntp/configure:4749:    CFLAGS="$CFLAGS-Wstrict-overflow"

sntp/configure:4750:    { $as_echo"$as_me:${as_lineno-$LINENO}: checking if $CC can handle-Wstrict-overflow" >&5

sntp/configure:4751:$as_echo_n"checking if $CC can handle -Wstrict-overflow... " >&6; }

sntp/configure:13848:     CFLAGS="$CFLAGS-Wstrict-overflow"

CommitLog:26872:  enable gcc -Wstrict-overflow for gsoc_sntp

CommitLog:26886:    enable gcc -Wstrict-overflow

CommitLog:27283:  Enable gcc -Wstrict-overflow

CommitLog:27289:    * Enable gcc -Wstrict-overflow

CommitLog:27294:    enable -Wstrict-overflow, use-Wno-strict-prototypes only w/OpenSSL

CommitLog:27421:    conditional to constant' warning with-Wstrict-overflow from testing if

ChangeLog:801:* Enable gcc-Wstrict-overflow for gsoc_sntp as well

ChangeLog:809:* Enable gcc-Wstrict-overflow

renxl@icserver:~/work/nios-kernel/software_cross/ntp-4.2.6p4$./configure --host=nios2-linux--prefix=$HOME/work/nios-kernel/software_cross/ntp-4.2.6p4/_install

问题二:

在运行客户端的时候出错:

Looking for host 192.168.101.180 andservice ntp

Error resolving 192.168.101.180: Servname not supported for ai_socktype (-8)

 1Jan 00:10:53 ntpdate[781]: Can't find host 192.168.101.180: Servname notsupported for ai_socktype (-8)

 1Jan 00:10:53 ntpdate[781]: no servers can be used, exiting

原因:因为ntp客户端访问ntp服务器是匿名访问,就是只知道ip地址不知道服务端口号所以socket连接服务器的时候socket返回错误-8就是找不到服务错误类型,需要修改一下客户端系统的系统文件,手动指定端口号,将ntp名跟端口号绑定:

root:/etc> cat services

shell  514/tcp cmd

shell  514/udp cmd

ntp     123/udp

ntp     123/tcp

问题三:

Ntpdate 192.168.101.174

1 Jan 02:32:13 ntpdate[692]:no server suitable for synchronization found

 

接着编译:

[root@bogon ntp-4.2.6p5]#make

ntp_loopfilter.c:520:27: error:?.OD_NANO?.undeclared (first use inthis function)

参考网上,修改 ntp_loopfilter.c:

[root@bogon ntp-4.2.6p5]#find ./ -name ntp_loopfilter.c

./ntpd/ntp_loopfilter.c

添加下面定义:

ifndef MOD_NANO

#define MOD_NANO 0x2000

#endif

问题四:

2 Jan 15:20:06ntpdate[847]: the NTP socket is in use, exiting

注释掉:port检查代码,ntpdate.c line:1773

                   /*     rc =bind(fd[nbsock], &addr.sa, SOCKLEN(&addr));

                            if (rc < 0) {

                                     if(EADDRINUSE == socket_errno())

                                               msyslog(LOG_ERR,"the NTP socket is in use, exiting");

                                     else

                                               msyslog(LOG_ERR,"bind() fails: %m");

                                     exit(1);

                            }*/

 

arm 编译:

../libntp/libntp.a(systime.o):In function `get_systime':

/home/renxl/work/nios-kernel/software_cross/ntp-4.2.6p4/libntp/systime.c:74:undefined reference to `clock_gettime'

../libntp/libntp.a(systime.o):In function `step_systime':

/home/renxl/work/nios-kernel/software_cross/ntp-4.2.6p4/libntp/systime.c:205:undefined reference to `clock_gettime'

../libntp/libntp.a(machines.o):In function `ntp_set_tod':

/home/renxl/work/nios-kernel/software_cross/ntp-4.2.6p4/libntp/machines.c:453:undefined reference to `clock_settime'

 

实验结果:

 全网源设备精准时间同步服务-方案:gps精准授时-ntp时间服务_第1张图片

 

NTP原理:

NTP工作原理

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

·        Device ADevice B的系统时钟同步之前,Device A的时钟设定为10:00:00amDevice B的时钟设定为11:00:00am

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

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

        全网源设备精准时间同步服务-方案:gps精准授时-ntp时间服务_第2张图片

 

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

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

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

·        Device A接收到该响应报文时,Device A的本地时间为10:00:03amT4)。

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

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

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

NTP的报文格式

NTP有两种不同类型的报文,一种是时钟同步报文,另一种是控制报文(仅用于需要网络管理的场合,与本文无关,这里不做介绍)。

NTP基于UDP报文进行传输,使用的UDP端口号为123;时钟同步报文封装在UDP报文中,其格式如下图所示。

       

 全网源设备精准时间同步服务-方案:gps精准授时-ntp时间服务_第3张图片

主要字段的解释如下:

·        LILeap Indicator):长度为2比特,值为“11”时表示告警状态,时钟未被同步。为其他值时NTP本身不做处理。

·        VNVersion Number):长度为3比特,表示NTP的版本号,目前的最新版本为3

·        Mode:长度为3比特,表示NTP的工作模式。不同的值所表示的含义分别是:0未定义、1表示主动对等体模式、2表示被动对等体模式、3表示客户模式、4表示服务器模式、5表示广播模式或组播模式、6表示此报文为NTP控制报文、7预留给内部使用。

·        Stratum:系统时钟的层数,取值范围为116,它定义了时钟的准确度。层数为1的时钟准确度最高,准确度从116依次递减,层数为16的时钟处于未同步状态,不能作为参考时钟。

·        Poll:轮询时间,即两个连续NTP报文之间的时间间隔。

·        Precision:系统时钟的精度。

·        Root Delay:本地到主参考时钟源的往返时间。

·        Root Dispersion:系统时钟相对于主参考时钟的最大误差。

·        Reference Identifier:参考时钟源的标识。

·        Reference Timestamp:系统时钟最后一次被设定或更新的时间。

·        Originate TimestampNTP请求报文离开发送端时发送端的本地时间。

·        Receive TimestampNTP请求报文到达接收端时接收端的本地时间。

·        Transmit Timestamp:应答报文离开应答者时应答者的本地时间。

·        Authenticator:验证信息。

 

Ntp协议分析:

 

NTP协议格式
NTP packet = NTP header + Four TimeStamps =48byte
NTP header : 16byte
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
|LI | VN |Mode | Stratum | Poll | Precision |Root Delay | Root Dispersion | Reference Identifier |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
LeapYearIndicator : 2bit
VersionNumber : 3bit
Mode : 3 bit
Stratum : 8bit
PollInterval : 8 bit
Percision : 8bit
Root delay : 32bit
Root Dispersion : 32bit
Reference Identifier : 32bit
Four TimeStamps : 32byte
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
| Reference Timestamp |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
Reference Timestamp : 64bit
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
| Originate Timestamp |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
Originate Timestamp : 64bit
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
| Receive Timestamp |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
Receive Timestamp : 64bit
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
| Transmit Timestamp |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
Transmit Timestamp : 64bit
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
| Authenticator (optional) (96) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
以下为我捕获的ntp客户端与服务端交互的协议包:
NTP client send packet:
/* NTP header: 16 bytes */
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
/* Originate Timestamp */
CA 10 E7 F9 00 10 62 4D
NTP server response packet:
/* NTP header: 16 bytes */
1C 02 04 EC 00 00 00 29 00 00 07 AF CA 70 01 22
/* Reference Timestamp */
CA 10 E5 43 4D FA C7 59
/* Originate Timestamp */
CA 10 E7 F9 00 10 62 4D
/* Receive Timestamp */
CA 10 E7 F8 F0 7A 59 74
/* Transmit Timestamp */
CA 10 E7 F8 F0 7B 42 AB
NTP协议与UNIX其它时间服务的比较
网络上的校时协议有好几种:
Day Time Protocol(RFC-867)
Time Protocol(RFC-868)
Network Time Protocol (RFC-1305)
Simple Network Time Protocol(RFC-2030)
最早使用的网络时间协定是RFC-867(port 13)和RFC-868(port 37)。Day TimeProtocol送出的码是ASCII码,直接表示日期、年份、时间及时区。Time Protocol送的是32 bits的binarynumber,以二进位表示自公元1900年1月1日零时起开始的秒数,时区都是格林威治时区。而Day Time Protocol和TimeProtocol都只能表示到秒,而且并没有估算到网络的时延。在每一版的UNIX中都有rdate指令, 可向其他UNIX工作站取时间, 如果您的要求不是很高,在局域网中是适合的。
Network Time Protocol使用port 123,64 bits的binary number,前32 bits和Time Protocol一样,后32 bits用以表示秒以下的部份,并加上网络延时量的估计.理论上可以精确到到2的-32次方秒,实际使用大约只有50ms(广域网)左右,在局域网可达1ms。在实际中您应找最近而且最稳定的Server作时间源。
SNTP算是NTP的一个子集,它不像NTP可以同時和多个Server对时, 一般在Client端下使用。
如果您要求实在不高,建议您使用rdate即可,简单又方便。如果您的精确度要求在秒以下,建议您使用SNTP。如果您有一群工作站需要同步或做较精密的时间运算,那么建议您使用NTP,操作系统最好是UNIX,其次是WinNT。Win95及时的解析度只有55ms,又不稳定,不建议使用。

Ntp协议解析

NTP协议中发送和接收的数据包类似都是48个字节也可以再多一些但只需前48个字节

就可以进行计算了。数据包的内容如下 

通过抓包分析出一个典型的请求数据包是这样的48字节 

1B 00 00 00 00 00 00 0000 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------------头部 

D0 AF 5F F5 23 D7 0800---------------Originate Timestamp (T1)出发时间戳有效位为8 bytes 

 

服务器端典型的回复数据包如下长度也为48字节 

1C 02 00 EC 00 00 06 EA00 00 0C A2 C0 A8 33 CA----数据包头部共16 bytes 

D0 AF 5E A3 F5 BD 72BC---------------Reference Timestamp 

D0 AF 5F F5 23 D7 0800---------------Originate Timestamp (T1) 

D0 AF 61 D7 CD 2E F911---------------Receive Timestamp ? (T2) 

D0 AF 61 D7 CD 2F F4BA---------------Transmit Timestamp ?(T3) 

收到数据包后本地再产生一个时间戳(T4) 

这里每个返回数据前4字节为秒的整数部分后4字节为秒的小数部分 

' NTP 协议中的时间是从1900年开始的。准确说秒数计数的起始时间为格林威治的19001

1000秒。我们这里另外必须有8个小时的时区补偿值。 

为了代码简洁减少数制转换发现发送NTP协议协议请求包时不用发准确的发送时间戳

用个虚构的时间戳数据就可以了因此这里NTP服务器返回的请求时间戳T1只用作数据

真实性检验而由程序在发送时刻获取一个正确的时间戳作为计算用T1就成。 

网络延时 = (T4-T1) -(T2-T3) 

误差补偿秒数 = ((T2-T1) +(T3-T4))/2; 

校对结果时间=现实时间+误差补偿秒数 

这里我们一般电脑用的时间精度在1秒以内就可以了因此每个时间戳处理都只用了其整

数部分。 

 

初始时间到时间 (1900-01-01-0-0-0)  ' 格林威治时间1900年一月一日000N

UDP协议、端口123

国家授时服务中心服务器端202.72.145.44  

 

CLIENT 一般设定 

len = 48, LI=0; VN=3MODE=3 STRATUM=0,POLL=4 PREC=-6,

JAN_1970:  0X83AA7E80 //1900-1970之间的秒数

NTPFRAC(X)   (4294*(X) +( (1981*(X))>>11)  )

USEC(X)       (  ((X)>>12) – 759*(   ( ((X)>>10 ) +32768)>>16 ))  

1. #define JAN_1970      0x83aa7e80      /* 2208988800 1970 - 1900 in sec

onds */  

2. #define NTPFRAC(x)(4294 * (x) + ((1981 * (x))>>11))  

3. #define USEC(x) (((x)>> 12) - 759 * ((((x) >> 10) + 32768) >> 16)) 

 

设置时间

获取当前时间填充到time  (time_t )结构中

 

算法:

前端时间无意中看了NTP(Network Time Protocal)后,顿时豁然开朗.
全网源设备精准时间同步服务-方案:gps精准授时-ntp时间服务_第4张图片

图中T1为客户端发送请求时间, T2为服务端接收到请求时间,T3为服务端向客户端发送响应的时间,T4为客户端接收到响应的时间。d为消息在网络上来回的时间,假设消息在网络上来回时间相同(这个是必须的假设,如果没有这个假设,以下的等式就多了一个变量,那么就无法求解了。而且这个假设也是合理的,毕竟网络上传输所需的时间是很短的,一般都在毫秒级),那么单趟传输所需时间就是2/d。假设客户端和服务端时间偏差为t。则有以下等式:
T2=T1+t+d/2;

T2-T1=t+d/2;

T4=T3-t+d/2;

T3-T4=t-d/2;


联立求解即得:
 d=(T4-T1)-(T3-T2); 
 t=((T2-T1)+(T3-T4))/2

当然,如果需要更为精确的结果,排除偶然网络不正常造成的影响,可以给求出来的d设定一个阈值D,当d>D时则让本次同步失效。

 

 

Win7开启ntp

Server 端设置(Run--> regedit):

  1、修改以下选项的键值HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer内的「Enabled」设定为1.

  该设置打开NTP服务器功能(默认是不开启NTP Server服务,除非电脑升级成为域控制站)

  2、修改以下键值HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\Config\AnnounceFlags设定为5.

  该设定强制主机将它自身宣布为可靠的时间源,从而使用内置的互补金属氧化物半导体 (CMOS) 时钟。

  如果要采用外面的时间服务器就用默认的 a 值即可.

  3、重启Win32Time服务: net stop w32Time && netstart w32Time

Client端设置(Run --> regedit):

  1、修改HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpClient

  SpecialPollInterval     值修改成十进制43200 (单位为秒,43200为12小时)

  SpecialPollTimeRemaining  值修改成[时间同步服务器],0 如:192.168.1.1,0

  2、更改默认更新服务器

  HKEY_LoCAL_MACHINE\SOFTWARE\MICROSOFT\WINDOWS\CURRENTVERSION\DATETIME\SERVERS\default

  3、重启Win32Time服务: net stop w32Time && netstart w32Time

全网源设备精准时间同步服务-方案:gps精准授时-ntp时间服务_第5张图片

全网源设备精准时间同步服务-方案:gps精准授时-ntp时间服务_第6张图片

六.设计思路

通过h5600代理ntp-server转发非网管设备的ntp时间请求。具体的过程如下图。

第一部分:网关跟ntp-server同步,即h5600定时启动本地的ntp-client跟指的的ntp-server同步自身时间。

第二部分:网关跟非网关,信道是DCC监控,非网关作为ntp-client发起请求,连接H5600进程的本地端口127.0.0.0123h5600进程将本地ip填入数据的后4字节,打扮成msdh帧通过dcc发到网关

第三部分:网关接到dccntp请求后将msdh帧解包,将数据打包成以太网包,发送给本地端口127.0.0.1:123,ntp_server服务端口号。

全网源设备精准时间同步服务-方案:gps精准授时-ntp时间服务_第7张图片


你可能感兴趣的:(工作经验积累)