| 基于互联网的网络校时软件开发 |
| 蒲应文 |
|
《软件报》2008年17期 邮发代号61-74
一、编程引子
网络上存在很多叫做“授时服务器”的主机,它们负责提供精确的时间,一般是由原子钟产生的。因此,我们只要做一个小程序来与授时服务器通信并按照其返回的准确时间来调整本机时间就可以了。
二、编程分析
1、通讯方法
用多个Winsock控件同时与多个授时服务器主机连接,用最先返回的时间来调整本机时间。本文所使用到的Winsock的主要属性、方法、事件如下:
①State属性:返回当前状态,取值如下:
sckClosed(常量为0):关闭状态
sckOpen(常量为1):打开状态
sckListening(常量为2):侦听状态
sckConnectionPending(常量为3):连接状态
sckResolvingHost(常量为4):解析主机中
sckHostResolved(常量为5):已解析主机
sckConnecting(常量为6):正在连接
sckConnected(常量为7):已经连接
sckClosing(常量为8):客户端正在关闭
sckError(常量为9):连接发生错误
②connect方法:用于客户端向远程发送一个连接请求,语法:Winsock.connect [IP,Port]
③getData方法:用于接收远程发送来的数据,语法:Winsock.getData 变量
④Close方法:关闭通信
⑤DataArrival事件:有数据到达时发生的事件,可以在这个事件中来getData发送来的数据
2、授时服务器
本文推荐9台速度比较快的授时服务器主机,它们的网址分别是:
time.nist.gov
time-a.nist.gov
time-b.nist.gov
nist1.datum.com
utcnist.colorado.edu
nist1.aol-ca.truetime.com
nist1.aol-va.truetime.com
time-a.timefreq.bldrdoc.gov
time-b.timefreq.bldrdoc.gov
只要连接到授时服务器,它就会自动返回一个包含时间的字符串,比如,连接到授时服务器time.nist.gov时返回的字符串为:“54526 08-03-01 13:42:53 59 0 0 190.2 UTC(NIST) *”(不包括引号),其中,字符串的前后各有一个不可见的字符。从返回的字符串中取出日期和时间,就可以调整本机的日期和时间了。
三、编程实现
1、界面设计
启动VB,新建一工程,点击“工程\部件”菜单项,在部件对话框中选择“Microsoft Winsock Control 6.0”后确定即可。如果没有这个复选框,可点击[浏览]按钮后在打开的[添加ActiveX控件]对话框选择MSWINSCK.ocx后点击打开,再点确定即可。在窗体上添加一个Winsock1控件,选择、复制、粘贴,创建数组控件;添加3个定时器控件Timer1(连接计次,Interval=100000,Enabled=True)、Timer2(校时进度指示,Interval=1000,Enabled=True)、Timer3(空闲计时,Interval=1000,Enabled=False);再添加几个标签(显示信息)。
2、核心代码
1)、初始化服务器
Dim SvrName(9) As String
Dim Flag As Boolean
Dim iWait as Integer
Dim N1, N2, N3 ’记次变量
Private Sub Form_Load()
SvrName(1)="time.nist.gov"
SvrName(2)="time-a.nist.gov"
’其它服务器设置,代码略
Call SetTime ’开始校时
End Sub
2)、开始校时
Private Sub SetTime()
For i = 1 To 9
Load Winsock1(i) ’加载控件
With Winsock1(i)
If .State=9 Then Exit Sub
If .State>0 Then .Close ’关闭
.Connect SvrName(i),13 ’连接
End With
Next
End Sub
3)、校时进度指示
Private Sub Timer2_Timer()
N2 = N2 + 1
If N2<20 Then LbMsg.Caption=LbMsg.Caption & ">"
End Sub
4)、连接计次处理
程序每10秒判断一次是否有服务器响应并信息返回,无信息返回则重新连接,每次校时最多连接3次,共需要30秒时间。
Private Sub Timer1_Timer()
N1 = N1 + 1
If N1 >= 3 Then
Timer1.Enabled = False
Timer2.Enabled = False
Call WskClose ’关闭连接
iWait = 1 : Flag = False
Timer3.Enabled=True ’空时
Exit Sub
Else
Call SetTime ’重新校时
End If
End Sub
Private Sub WskClose()
For k = 1 To 9
If Winsock1(k).State>0 Then Winsock1(k).Close
Unload Winsock1(k)
Next
End Sub
5)、判断返回信息
Private Sub Winsock1_DataArrival(…)
Winsock1(Index).GetData S,vbString
If Flag Then Exit Sub ’选最快主机
Flag = True ’成功返回信息
dt=CDate(Mid$(S,8,17))+8#/24#
Date=dt : Time=dt ’校时
Timer1.Enabled = False
Timer2.Enabled = False
iWait = 15 : Flag = False
LbMsg = "开始校时:成功!"
LbWt.Caption=iWait*60 & "秒后再校"
Call WskClose
Timer3.Enabled=True ’空时
End Sub
6)、空闲等待处理
Private Sub Timer3_Timer()
N3 = N3 + 1
If N3 >= 60 * iWait Then
N3 = 0: N2 = 0: N1 = 0
Timer3.Enabled = False
Call SetTime ’开始校时
Timer1.Enabled = True
Timer2.Enabled = True
End If
End Sub
四、编程后记
网络校时的关键是如何获取到精确的时间,本文通过互联网上的授时服务器主机获取精确时间,实时校正本机的时间。如果局域网中还有计算机需要校时,就可以本机的时间为基准,使用Windows的“Net Time”命令完成校时。调试环境:WinXp+VB6。
|
|
文章检索
编程>热门文章
|