写作目的:(此段可跳过)

同步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秒以内(如果你不用你的爱机控制导弹飞行或者航天发射,应该够用了),详见源码。

c++语言怎么从internet上某个时间服务器获取时间信息,在VC++中实现同步Internet时间...相关推荐

  1. 从Internet时间服务器获取标准格林尼治时间

    从Internet时间服务器获取标准格林尼治时间 由于本机系统时间不准确,所以决定从Internet 时间服务器获取标准时间来校正  系统时间,说干就干. 程序设计步骤如下: 1.  新建一个工程: ...

  2. 《Linux高性能服务器编程》学习总结(四)——TCP/IP通信案例:访问Internet上的Web服务器...

    第四章      TCP/IP通信案例:访问Internet上的Web服务器 HTTP协议是工作在应用层上的协议,其应用十分广泛,而在进行通信的过程中,经常使用HTTP代理服务器.HTTP代理服务器主 ...

  3. 国内可用的Internet时间同步服务器地址(NTP时间服务器) 好在阿里云提供了7个NTP时间服务器也就是Internet时间同步服务器地址(转)...

    国内可用的Internet时间同步服务器地址(NTP时间服务器) 好在阿里云提供了7个NTP时间服务器也就是Internet时间同步服务器地址 ntp1.aliyun.com ntp2.aliyun. ...

  4. C#net6实现Linux系统下修改IP地址、修改系统时间、获取内存信息、获取磁盘信息、重启系统

    C#net6实现Linux系统下修改IP地址.修改系统时间.获取内存信息.获取磁盘信息.重启系统 背景 项目背景 实现思路 代码实现 背景 随着微软.net core的出现,C#程序实现跨平台不在困难 ...

  5. 前后端上传图片(上传发票并获取发票信息)

    前后端上传图片(上传发票并获取发票信息) React+Antd上传图片 后端SpringBoot接收图片 SpringBoot后端解析发票信息 React+Antd上传图片 上传图片upload组件 ...

  6. matlab产生时间数组以月为单位_Matlab中处理日期与时间的函数

    Matlab用三种格式来表示日期与时间 (1)双精度型日期数字:一个日期型数字代表从公元0年到某一日期的的天数,例如,2008年8月26日夜时0点钟被表示为733646,而这同一天的中午12点就被表示 ...

  7. 从网络时间服务器获取并打印当前时间

    很多程序要求设备的时间精准,例如Unix系统中的make命令.设备上的时间可能不够准确,需要和网络中的时间服务器同步.可以编写一个Python客户端,让设备上的时间和某个网络时间服务器同步.要完成这一 ...

  8. 更新域内计算机时间,Word2013如何自动更新文档中的日期和时间?如何设置打印前自动更新域...

    在Word2013文档中插入日期和时间,如何实现自动更新,下面小编就给大家介绍一下Word2013中自动更新文档中的日期和时间的方法,而且,使用这个办法还可以插入会自动更新的时间,最后,还给大家分享了 ...

  9. 大话手游时间服务器哪个最新,大话西游手游教你玩转时间服!时间服大揭秘有哪些变化...

    时间服公测在即,大家一定迫不及待想重温一把经典情怀了! 时间服和免费服在玩法上有哪些不同呢? 1.装备大变样 目前时间服是没有神兵.仙器的 ;只有新手装备.高级装备(60级.100级.2转120级装备 ...

最新文章

  1. php多线程多核,Linux查看CPU个数/多核/多线程的查看
  2. CSS盒子模型之CSS3可伸缩框属性(Flexible Box)
  3. python爬虫软件-8个最高效的Python爬虫框架,你用过几个?
  4. json 反序列化 父子类型_Jaskson精讲第7篇-类继承关系下的JSON序列化与反序列化JsonTypeInfo...
  5. 基于JDK7 NIO2的高性能web服务器实践之二(转)
  6. WebUserControl归纳
  7. 做一个略调皮的个人主页--结构篇
  8. 哪些情况需用到数据分析工具
  9. 过半博士后考虑退出原领域,Nature呼吁不能因疫情失去科学的下一代
  10. 三峡大学学生选课系统_201014119_赵敏_三峡大学学生选课系统.doc
  11. Kopernio插件+SCI-HUB最新可用网址
  12. linux无人值守安装实验,无人值守批量安装linux操作系统
  13. sql 语句实现电话号筛选,例如:AABB,ABAB
  14. 电脑版 钉钉 卡顿 解决办法
  15. 天下文章一大抄 mysql远程连接
  16. ubuntu14.04+cuda8.0(gtx1080)下tensorflow的安装
  17. 专题地图制作之POI获取
  18. 社交营销还是要走到线下
  19. 视频教程-SpringBoot2+Vue+AntV前后端分离开发项目实战-Java
  20. 俄17岁少年推出网聊新招

热门文章

  1. 没了IDE,你的Java项目还能Run起来吗~
  2. 资深架构专家聊架构之道:灵活、稳定、高可用15点精要
  3. 互联网人,从来不说人话!
  4. 以Jar形式为Web项目提供资源文件(JS、CSS与图片)
  5. 关于freemarker的classic_compatible属性的使用场景和解决
  6. Spring 框架基础(02):Bean的生命周期,作用域,装配总结
  7. hadoop--集群时间同步(可不同步)
  8. .Net字符暂存池(String Intern Pool)
  9. 职场必须要会的餐桌礼仪
  10. Sublime配置VI插件后 快捷键总结