最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 正文

NTP网络授时系统设计与实现——客户端时钟同步软件设计与实现

来源:动视网 责编:小OO 时间:2025-09-30 01:40:53
文档

NTP网络授时系统设计与实现——客户端时钟同步软件设计与实现

第5章客户端时钟同步软件设计与实现5.1概述在NTP网络授时系统中,各子网中的路由器可从NTP服务器获取标准时间,并为其它终端用户提供授时服务。同时,其它终端用户也可以直接从NTP服务器获取标准时间。NTP网络授时系统的时钟同步软件,即部署在需通过网络获取精确时间的各windows终端上。时钟同步软件共包括三个功能模块:系统管理、定时器和时钟获取与校正。系统管理模块,用于设置作为时钟参照的NTP服务器的地址、每次对时发送NTP报文的次数、对时间隔等参数。定时器模块,用于定时或手工发起时钟同步请
推荐度:
导读第5章客户端时钟同步软件设计与实现5.1概述在NTP网络授时系统中,各子网中的路由器可从NTP服务器获取标准时间,并为其它终端用户提供授时服务。同时,其它终端用户也可以直接从NTP服务器获取标准时间。NTP网络授时系统的时钟同步软件,即部署在需通过网络获取精确时间的各windows终端上。时钟同步软件共包括三个功能模块:系统管理、定时器和时钟获取与校正。系统管理模块,用于设置作为时钟参照的NTP服务器的地址、每次对时发送NTP报文的次数、对时间隔等参数。定时器模块,用于定时或手工发起时钟同步请
第5章 客户端时钟同步软件设计与实现

5.1 概述

在NTP网络授时系统中,各子网中的路由器可从NTP服务器获取标准时间,并为其它终端用户提供授时服务。同时,其它终端用户也可以直接从NTP服务器获取标准时间。NTP网络授时系统的时钟同步软件,即部署在需通过网络获取精确时间的各windows终端上。时钟同步软件共包括三个功能模块:系统管理、定时器和时钟获取与校正。

系统管理模块,用于设置作为时钟参照的NTP服务器的地址、每次对时发送NTP报文的次数、对时间隔等参数。

定时器模块,用于定时或手工发起时钟同步请求。在通常状况下,系统按用户设置的对时间隔,自动与NTP服务器进行时间同步。在需要的时候,也可以由用户进行手工同步

时间获取与校正模块:用于根据系统指定的参数,构造NTP消息报文,从NTP服务器获取精确的标准时间。系统根据时钟同步的方式(手工或定时)本地时间,使系统内部各个节点的时钟保持一致。任意一个时钟同步客户端发起时钟同步消息,授时服务器返回系统时钟信息,客户端根据时钟信息调整本地时间。

5.2 时钟同步软件静态结构图

5.2.1 时钟同步软件整体结构

时钟同步软件中,定时同步与手工同步的流程基本相同,系统的整体结构如下图所示:

图5-1  时间同步的整体模型结构图

5.2.2 时钟同步软件的类图

分析时钟同步软件的结构,进一步细化系统中各种对象,以完成对系统中的类进行定义。

图5-2  时钟同步模块的类图

5.2.3 系统主要类设计

系统主要类的设计说明如下:

1. SYSTEMTIME类

表5-1 SYSTEMTIME类设计

表示系统时间的类
属性访问权限描述
wYearpublic
wMonthpulic
wDayOfWeekpulic一周第几天
wDaypublic
wHourpublic小时
wMinutepulic
wSecondpulic
wMillisecondpublic毫秒
操作参数描述
SYSTEMTIME构造函数
2. SynClient类

表5-2 SynClient类设计

时钟同步客户端类
属性访问权限描述
offsetprivate时钟偏差
maxoffsetprivate最大时钟偏差
ServerTimepublic标准时间
BackTimeprivate报文回收时间
操作参数描述
getoffsetlong value获取时钟偏差
getmaxoffset获取最大时钟偏差
setmaxoffsetlong value设置最大时钟偏差
getBackTime获取报文回收时间
setBackTimeSYSTEMTIME systemtime设置报文回收时间
3. ConstructPacket类

表5-3 ConstructPacket类设计

构建NTP同步报文

属性访问权限描述
LIpublicLI标志

VNpublicVN标志

Modepublic模式
Stratumpublic层级
Pollpublic轮询间隔
Precisionpublic精度
RootDelaypublic根延时
RefTimepublic服务器对时时间
OriTimeprivate报文发送时间
RecTimeprivate报文接收时间
TransTimeprivate报文回复时间
操作参数描述
ConstructPacket构造函数
getOriTime获取OriTime时间戳

setOriTimelong time设置OriTime时间戳

getRecTime获取RecTime时间戳

setRecTimelong time设置RecTime时间戳

getTransTime获取TransTime时间戳

setTransTimelong time设置TransTime时间戳

4. SynTask类

表5-4 SynTask类设计

时间同步任务类
属性访问权限描述
Addressprivate服务器地址
Intervalprivate同步间隔
操作参数描述
SynTask构造函数
getAddress获取服务器地址
setAddressIPAddress ip设置服务器地址
getInterval获取同步间隔
setIntervallong para设置同步间隔
Check时钟检查
Run发起时钟同步请求
5. SynServer类

表5-5 SynServer类设计

同步通信接口类
属性访问权限描述
skpublicsocket接口

packetprivate同步报文
操作参数描述
SynServer构造函数
getpacket获取报文
setpacketConstructPacket pk设置报文
sendpacketConstructPacket pk, socket sk发送报文
recvpacketConstructPacket pk, socket sk接收报文
5.3 时间获取与校正模块动态结构图

5.3.1 时钟同步算法

时钟同步最主要的问题是解决同步消息传输延迟的计算问题。由于本系统采用单服务器的方式,解决这一问题的办法,是通过时钟同步的客户端向授时服务器多次发送带有时间戳的同步消息报文,并接收授时服务器返回的时钟同步消息报文,计算并记录每次的时间延迟,并选取值最小的一次记录,用此次的标准时间来校正本地时钟[28]。整个过程如下图所示:

图5-3  时钟同步的活动图

5.3.2 定时同步

定时同步,是指客户端按系统设置的同步时间间隔,定时向授时服务器发送时钟同步请求,保证本地时钟与标准时间保持一致,过程如下:

1. 定时时间到,定时器触发发送时钟同步请求;

2. 时钟同步客户端SynClient向指定的授时服务器发送时钟同步消息报文;

3. 授时服务器接收时钟同步消息报文,将接收时间和响应时间封装在报文中,发回客户端;

4. 客户端接收返回报文,计算出本地时钟与标准时间的偏差,校正本地时钟。

一次定时同步的时序图与协作图如下:

图5-4  定时同步时序图

图5-5  定时同步的协作图

5.3.3 手工同步

手工同步,是指由用户人工触发时钟同步事件,其过程与定时同步基本相同,事件流描述如下:

1. 用户发送时钟同步请求;

2. 时钟同步的客户端向授时服务器发送时钟同步消息报文;

3. 授时服务器接收时钟同步消息报文,将接收时间和响应时间封装在报文中,发回客户端;

4. 客户端接收返回报文,计算出本地时钟与标准时间的偏差,校正本地时钟。

5. 向用户反馈同步信息。

手工同步的时序图与协作图如下:

图5-6  手工同步时序图

图5-7  手工同步的协作图

5.4 时间获取与校正模块的实现

5.4.1 总体实现

时间获取与校正模块是时钟同步软件的核心,其主要任务是向网络中的NTP服务器发送时钟同步请求并接收服务器返回的带有时间戳的NTP报文,计算网络延时和时间偏差,修正本地主机的系统时间。时间获取与校正的主要流程如下所示。

图5-8  时间获取与校正流程图

5.4.2 时钟获取与校正的关键技术点

时钟同步模块与授时模块的运行环境不同,部署在windows操作系统上,在此用C#编程实现。

其实现的要点有:

1. NTP报文的封装

根据NTP报文的格式,客户端首选构建一个NTP报文,其主要字段的设置如下:

表5-1  客户端NTP报文时间戳设置

字段名称
LI00
VN3
Mode3
Stratum2
Poll忽略
Precision忽略
Root Delay忽略
表5-1  客户端NTP报文时间戳设置(续表)

字段名称
Root Dispersion忽略
Reference Identifier忽略
Reference Timestamp忽略
Originate Timestamp忽略
Receive Timestamp忽略
Transmit Timestamp取报文发送时间
Authenticator可选
其中,传送时间戳Transmit Timestamp的获取代码段如下:

DateTime t1900 = Convert.ToDateTime("1900-01-01 00:00:00");

long tick1900 = t1900.Ticks;

long tick = DateTime.Now.Ticks;

long s1900 = ((tick - tick1900)-36000000000*8)/10000000;

long s1900s = ((tick - tick1900) - 36000000000 * 8) % 10000000;

byte[ ] temp = BitConverter.GetBytes(s1900);

for (int j = 0; j < 4; j++)

{

Packet[40 + j ] = temp[3-j ];

}

temp = BitConverter.GetBytes(s1900s);

for (int k = 4; k < 8; k++)

{

   Packet[40 + k] = temp[7 - k];

}
因为UTC时间表示为当前与1900年1月1日0时相关的秒数,而在C#中,时间的Ticks属性获取的是与公元元年1月1日0时的时间差,计数单位是毫微秒,故先取得1900年第一天的Ticks值,再获取当前时间的Ticks值,两者相减,并除以一个系数,其值与余数就分别为UTC时间的整数和小数部分。Transmit Timestamp时间戳用8个字节位表示,其中前32位表示秒数的整数部分,后32位表示秒数的小数部分。

2. 与服务器间的socket通讯

网络编程要用到的两个命名空间[29]是System.Net和System.Net.Sockets。System.Net命名空间通常与较高层的操作有关,例如 download或upload,试用HTTP和其他协议进行Web请求等等,而System.Net.Sockets命名空间所包含的类通常与较低层的操作有关。如果要直接使用Sockets或者TCP/IP之类的协议,这个命名空间的类是非常有用的。

在.Net中,System.Net.Sockets 命名空间为需要严密控制网络访问的开发人员提供了 Windows Sockets (Winsock) 接口的托管实现。System.Net 命名空间中的所有其他网络访问类都建立在该套接字Socket实现之上。在应用程序端或者服务器端创建了Socket对象之后,就可以使用Send/SentTo方法将数据发送到连接的Socket,或者使用Receive/ReceiveFrom方法接收来自连接Socket的数据。

针对Socket编程,.NET 框架的Socket 类是 Winsock32 API 提供的套接字服务的托管代码版本[30]。其中为实现网络编程提供了大量的方法,大多数情况下,Socket 类方法只是将数据封送到它们的本机 Win32 副本中并处理任何必要的安全检查。

在使用之前,你需要首先创建Socket对象的实例,这可以通过Socket类的构造方法来实现:

Public Socket(AddressFamily addressFamily,SocketType socketType,ProtocolType protocolType); 
其中,addressFamily 参数指定 Socket 使用的寻址方案,socketType 参数指定 Socket 的类型,protocolType 参数指定 Socket 使用的协议。

在本系统中,NTP客户端使用UDP方式与服务器通信,所以在创建Socket实例时,用的是Socket的无连接的数据报形式:

Socket temp = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 
由于UDP是一种无连接的协议,因此,为了使应用程序能够发送和接收UDP数据包,需要两个步骤:

1.创建一个Socket对象;

2.将创建的Socket对象与本地IPEndPoint进行绑定。

经过这两步,创建的Socket对象就能够在IPEndPoint上接收流入的UDP数据包,或者将流出的UDP数据包发送到网络中任意其他设备上。使用UDP通信时,不能使用标准的Send()和Receive()方法,须使用另外的SendTo()和ReceiveFrom()方法。

在客户端使用Socket通信,因为客户机不需要在指定的UDP端口等待流入的数据,因此,不必要使用Bind()方法,而是使用在数据发送时系统随机指定的一个UDP端口,也使用同一个端口来接收返回的消息。UDP客户机程序首选定义一个IPEndPoint,UDP服务器将发送数据包到这个IPEndPoint。本系统客户端Socket通信功能的代码片断如下:

try

{

    myIP = IPAddress.Parse(TBip.Text);

}

catch { MessageBox.Show("IP地址不正确,请重新输入!"); }

try

{

    BTsend.Enabled = true;

myServer = new IPEndPoint(myIP, 123);

//创建一个Socket实例sk

    sk = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

}

catch (Exception ee) { MessageBox.Show(ee.Message); }

    //构造NTP消息包

    ConstructPacket pk = new ConstructPacket();

data = pk.Packet;

//发送NTP消息包

sk.SendTo(data, data.Length, SocketFlags.None, myServer);

//接收服务器返回的NTP消息包

    sender = new IPEndPoint(IPAddress.Any, 0);

    EndPoint Remote = (EndPoint)sender;

    byte[] rdata = new byte[256];

    int recv = sk.ReceiveFrom(rdata, ref Remote);
其中,SendTo()方法指定要发送的数据和目标机器的IPEndPoint。ReceiveFrom()方法同SendTo()方法类似,但是使用EndPoint对象声明的方式不一样,利用ref修饰,传递的不是一个EndPoint对象,而是将参数传递给一个EndPoint对象。

3. 本地时钟的获取与设置

在网络授时系统的客户端,发起时钟同步请求时,首先要获取本地时钟,在收到服务器返回的NTP报文后,要计算出本地时钟与标准时钟的偏差,然后对本地时钟进行校正,将其时间设置为标准时间。

本系统在 .NET架构的C#环境下开发,对本地时间的获取和设置分别采用了两种不同的方式。

1.获取本地时钟,可以直接创建一个DateTime类的实例,然后用DateTime.Now属性,即可得到本地时间。但是本系统需要的是UTC时间,所以不必直接获取本地时间,而是通过DateTime对象的Ticks属性来获取时间差,并通过必要时间基准和时区的转换,得到NTP报文所需要的UTC时间。这段功能代码在上面Transimit Timestamp时间戳的获取代码中已经包含,在此不再重复。

2.设置本地时钟。在C#中,与时间相关的类中没有合适的直接设置本地时间的方法,本系统设置时间通过调用Win32 API的SetSystemTime函数来实现。

首先,必须定义对SetSystemTime函数的调用声明:

[DllImport("kernel32.dll")]

private extern static uint SetSystemTime(ref SYSTEMTIME lpSystemTime);
       然后定义一个要传递给本机方法并从本机方法接收的结构。

private struct SYSTEMTIME 

{

    public ushort wYear;

    public ushort wMonth; 

    public ushort wDayOfWeek; 

    public ushort wDay; 

    public ushort wHour; 

    public ushort wMinute; 

    public ushort wSecond; 

    public ushort wMilliseconds; 

}
最后,将通过NTP时钟同步计算出的标准时间赋值到SYSTEMTIME结构的一个实例,直接调用SetSystemTime设置即可。

private void SetTime()

{

    SYSTEMTIME systime = new SYSTEMTIME();

//将标准时间赋值到systime对象

……代码略

    // 设置本地时间

    SetSystemTime(ref systime);

}
5.4.3 系统实现的主要功能界面

1. 系统管理和参数设置

为了便于时间同步软件相关参数的设定,如NTP服务器地址、同步时间间隔、每次同步发送的数据包个数等等,必须提供用户与计算机进行交互的手段。本系统通过一个图形用户界面,用户可以方便地调整各项参数的值。系统管理的界面如下图。

图5-9  系统管理界面

2. 定时器

定时器平时在系统后台运行,当到达系统指定的时间间隔时,向时钟同步软件发起同步请求。用户也可以通过定时器的菜单,手工发起时钟同步请求,或者调用系统管理模块进行系统参数的设置。定时器的实现界面如下图。

图5-10  定时器的实现界面

文档

NTP网络授时系统设计与实现——客户端时钟同步软件设计与实现

第5章客户端时钟同步软件设计与实现5.1概述在NTP网络授时系统中,各子网中的路由器可从NTP服务器获取标准时间,并为其它终端用户提供授时服务。同时,其它终端用户也可以直接从NTP服务器获取标准时间。NTP网络授时系统的时钟同步软件,即部署在需通过网络获取精确时间的各windows终端上。时钟同步软件共包括三个功能模块:系统管理、定时器和时钟获取与校正。系统管理模块,用于设置作为时钟参照的NTP服务器的地址、每次对时发送NTP报文的次数、对时间隔等参数。定时器模块,用于定时或手工发起时钟同步请
推荐度:
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top