在VC++中实现同步Internet时间

校时原理:
        互联网上有很多时间服务器能够提供准确的时间,我们通过连接到这样的服务器来获取时间值。这里向大家介绍一下服务器传来的数据格式先。数据一共四个字节(4 Byte),我们可以在接收数据后对它进行“重新组装”,把组装所得的值放在一个32位的整数里,这个值的意义是:自190011000 服务器发送这个时间数据时 所经历的秒数。显然,任何一个时刻到1900年所经历的秒数是唯一的,因此,由服务器传来的时间数据即可推出现在的时间,然后用API函数调整系统的时间即可。


流程图如下:


设计目标:

        好了,我们的目标是:(没有蛀牙~)
    -_-!!
    常言说一图千言,我们还是看图吧:

 

 

 

程序的实现:

从技术角度来看,解决三个问题即可:
1. 通过网络通信从服务器获取时间数据。

2. 处理基于1900年的时间数据,转化为我们常见的时间形式。

3. 解决网络造成的延时问题。

下面分条讲述:

1.
通过网络通信从服务器获取时间数据。

至于接收数据,没什么可说的,这里用CSocket就可以了。

 

代码片断:

    CSocket sockClient;
    sockClient.Create();            
// 创建socket

    
// for debug
    m_info  +=   " Connect server:  "   +  strServer  +   " " ;
    UpdateData(FALSE);
    
// for debug

    sockClient.Connect((LPCTSTR)strServer, 
37 );  //  strServer:时间服务器网址; 37:端口号

   DWORD dwTime = 0; //用来存放服务器传来的标准时间数据 
   sockClient.Receive(&dwTime, sizeof(dwTime)); //接收服务器发送来得4个字节的数据 
   dwTime = ntohl(dwTime);
   sockClient.Close();
   if(0 == dwTime) return FALSE;


 

到此为止,服务器传来的时间数据经过“重新组装”已经正确放置到DWORD类型的变量 dwTime 里面了。下面我们接着对其进行必要的处理。


2.
处理基于1900年的时间数据,转化为我们常见的时间形式。

在前面我们提到,时间数据已经正确放置到变量 dwTime 里面了。那么,怎样由它得到现在的时间呢?

微软已经给我们提供了一个很好用的时间类:CTime。不过,MFCCTime类的时间起点是基于1970年的,而dwTime 里面的秒数是从1900年计时的

CTime?无法由 dwTime 中的数据直接构造CTime类的对象。

 

 

没错,我就是在论坛上经过讨论找到答案的。说起最终敲定的实现方法,其实很简单- 改变计时基准。


时间转换的方法如下:

 

1.  用 COleDateTime 和 COleDateTimeSpan 算出190011000 197011000 所经历的秒数 dwSec00to70

2.  dwTime 中减去 dwSec00to70。此后,dwTime 所代表的就是自197011000秒以来逝去的秒数――显然,dwTime 已经被我们转变为基于1970年的时间值了,这回可以用CTime进行处理了。

 怎么样?不复杂吧。(想起了近几天屡试屡败的经历和查阅的N多资料,自己吐血先)

代码片断:

     // 服务器传来的数据是自从1900年以来的秒数
    
// 取得 1900~1970 的时间差(以秒数计算) ,放在dwSpan里面
    COleDateTime t00(  1900 1 1 0 0 0  );  //  1900.1.1 00:00:00 
    COleDateTime t70(  1970 1 1 0 0 0  );  //  1970.1.1 00:00:00 

    COleDateTimeSpan ts70to00 
=  t70  -  t00; 
    DWORD dwSpan 
=  (DWORD)ts70to00.GetTotalSeconds(); 
    ASSERT( dwSpan 
==   2208988800L  ); 
    
    
// 把时间变为基于1970年的,便于用CTime处理
    dwTime  -=  dwSpan;        
    
// 考虑网络延迟因素
    dwTime  +=  dwDely;
    
// 构造当前时间的CTime对象
    CTime timeNow  =  (CTime)dwTime;

    
// for debug
    m_info  +=  timeNow.Format( " %Y.%m.%d  %H:%M:%S  " );
    UpdateData(FALSE);
    
// for debug



3.

解决网络造成的延时问题。

    在从服务器获取时间数据时,由于网络本身的不稳定性,一般会有时间上的延迟(几秒以内),这样一来,从服务器接收到的数据总早于的真实时间。解决的办法是设定一个计时器,计算出本机从开始网络连接到接收完数据所耗费的时间dwDelay,然后加到 dwTime 上进行补偿。这样一来误差就可以控制在1秒以内(如果你不用你的爱机控制导弹飞行或者航天发射,应该够用了),详见源码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值