文档章节

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

rise-worlds
 rise-worlds
发布于 2016/06/20 13:35
字数 1339
阅读 0
收藏 0

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

写作目的:(此段可跳过)
    同步Internet时间,即通过Internet的校时网站传来的数据校准本机时间。但是现在网络上查到的相关编程资料并不多,且其中多是VB和Delphi的代码,VC的代码我还没找到过。是这个东西太难了?应该不是;是太简单了?那也总该有人写吧。
   我认为,自己懂和让别人懂压根不是一回事,我写这篇文章,目的当然是后者。当然,理工科出身的河蚌不大可能像文科出身的河蚌那样修出光彩夺目的珍珠来,所以,行文有不妥之处,欢迎指正。
校时原理:
        互联网上有很多时间服务器能够提供准确的时间,我们通过连接到这样的服务器来获取时间值。这里向大家介绍一下服务器传来的数据格式先。数据一共四个字节(4 Byte),我们可以在接收数据后对它进行“重新组装”,把组装所得的值放在一个32位的整数里,这个值的意义是:自1900年1月1日0时0分0秒 至 服务器发送这个时间数据时 所经历的秒数。显然,任何一个时刻到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;                //用来存放服务器传来的标准时间数据
    unsigned char nTime[8];            //临时接收数据
    memset(nTime, 0, sizeof(nTime));

    sockClient.Receive(nTime, sizeof(nTime));    //接收服务器发送来得4个字节的数据
    sockClient.Close();                //关闭socket

//for debug
    m_info += "Connect shut down. ";
    UpdateData(FALSE);
//for debug

    dwTime += nTime[0] << 24;        //整合数据   
    dwTime += nTime[1] << 16;
    dwTime += nTime[2] << 8;
    dwTime += nTime[3];       

if(0 == dwTime)    return FALSE;

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


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

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

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

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

用C的函数库?我尝试了多次,N次碰壁。

说起最终敲定的实现方法,其实很简单- 改变计时基准。

时间转换的方法如下:

1.  用 COleDateTime 和 COleDateTimeSpan 算出1900年1月1日0时0分0秒 到 1970年1月1日0时0分0秒 所经历的秒数 dwSec00to70。

2. 从 dwTime 中减去 dwSec00to70。此后,dwTime 所代表的就是自1970年1月1日0时0分0秒以来逝去的秒数――显然,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秒以内(如果你不用你的爱机控制导弹飞行或者航天发射,应该够用了),详见源码。

本文转载自:http://www.cnblogs.com/flying_bat/archive/2007/10/11/921033.html

rise-worlds

rise-worlds

粉丝 3
博文 1760
码字总数 1380
作品 0
深圳
程序员
私信 提问
用vc++做基于概率算法的算法动态演示系统

1、内容提要: 设计并实现典型算法的动态模拟演示,如:数值概率计算、在一个数组中找到“a”的Las Vegas算法与Monte Carlo算法、快速排序算法、验证两个数组的乘积是否正确、商旅问题等的动...

卡卡110120
2014/05/08
123
2
用ICE开发分布式程序

ICE是ZeroC公司开发的一款高效的开源中间件平台,全称是Internet Communications Engine。 它的主要设计目标是: • 提供适用于异种环境的面向对象中间件平台。 • 提供一组完整的特性,支持...

Waiting4you
2009/06/08
4.6K
1
做一款模仿《全民K歌》的音乐评分软件

详细需求: 1、 大部分功能模仿全民K歌实现 2、 歌词同步显示 3、 可以离线运行 4、 麦克风声音输入后,可以实时对比进行打分 5、 提供演示DEMO 6、由于时间很紧,必须要有现成代码,或者有核...

肖先生
2018/08/01
0
0
host、dig、nslookup 查询DNS命令

host 命令: 一般格式: host 域名 host -a 域名 常用选项: -a:相当于"-v -t any"。 -t type:指定要查询的记录类型。默认查询A、AAAA、MX记录。 -v:详细方式输出。 [root@BJ-IDC-NTP-002...

zhailibao
2015/09/28
899
0
vc升级失败恢复快照后数据不一致问题

第一次故障现象: 下午192.168.146.1 vc5.5升级6.0失败后回滚。Vcenter、DB和SSO均做的是带内存的快照。当时检查恢复完能连上vc和web client。当天晚上发现vc连接中断,第二天早上再次出现中...

xjsunjie
2017/10/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

如何更改iOS应用程序的名称?

我前几天用一个愚蠢的开发代码名称开始了一个iPhone项目,现在我想改变项目的名称,因为它已经接近完成了。 但是我不知道如何使用Xcode来做这件事,尝试在info.plist文件中更改应用程序的名称...

技术盛宴
25分钟前
3
0
关于win10tensorflow的配置(CPU+GPU)

主要内容 CPU篇 GPU篇 【前期准备与注意事项】 环境:window1064位+python36(37)+CUDA9.0+cuDNN7.6+tensorflow_gpu-1.12.0 软件:anaconda+pycharm 硬件:有nvidia显卡的笔记本或台式(非A...

放只虎归个山
34分钟前
2
0
C#中的多行字符串文字

有没有一种简单的方法可以在C#中创建多行字符串文字? 这是我现在所拥有的: string query = "SELECT foo, bar"+ " FROM table"+ " WHERE id = 42"; 我知道PHP有 <<<BLOCKBLOCK; C#是......

javail
41分钟前
4
0
微信支付之小微商户扫盲!支持信用卡,免营业执照!

微信支付商户申请面向线下小微商户开放,符合条件的微信支付服务商可为小微商户发起接入申请。无需营业执照。 小微商户日收款额度为5万元~30万元 。 信用卡支付日限额为1千;月限额1万。 结算...

吴伟祥
今天
4
0
大话SDWebImage(三)-- 图片下载层

四、图片下载层 SDWebImageDownloader是处理图片下载的类 4.1 图片下载步骤 首先介绍下dispatch_barrier,GCD中的dispatch_barrier目的是在并发队列实现串行的效果,创建下载任务SDWebImageD...

aron1992
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部