c++语言怎么从internet上某个时间服务器获取时间信息,VC知识库BLOG-hATEmATH的网上田园-在VC++中实现同步Internet时间...

喂马 劈柴 做一个幸福的人

2008年11月

日一二三四五六

2627282930311

2345678

9101112131415

16171819202122

23242526272829

30123456

公告

◇ 欢迎来到这里的每一位朋友。

◇ 无需注册即可评论或留言。

◇ 文章无"转载(ZT)"字样均为原创。

◇ "随笔分类"中包含我的所有随笔

留言簿(13)

随笔分类

随笔档案

文章分类

文章档案

相册

工具网站

搜索

最新评论

应该把步骤写得开一点,让我这样的菜鸟都能一眼看懂才是嘛!给我弄了半天才看明白,不过还真的可行.

--high

这位大哥 能否详细讲解一下SKYEYE如何安装与配置嵌入式开发环境

我在Fedora core linux 13.8下安装在第一步安装

m68k-elf-tools-20031003.sh

报告 tail:无法打开"¥43"读取数据:没有那个文件

我不知道是什么原因指点指点

--刘

"正在看文件系统的编程部分"

啥书讲文件系统,貌似很深奥

很勤劳啊,呵呵

--hz

HATEMATH的作品,怎么会有"冬天的落阳"署名,

马甲!

--马甲

这两天接触一些svg方面的东西,里面图片也是base64.

--sjdev

C上升到哲学的高度啦??!! 支持~

--玻璃小屋

无招胜有招,没有必要啃熟了那些刁钻的东西才认为精通了

--lostpencil

希望大家踊跃发言,也给我们这些门外汉一些启示。

我自己觉得关键得自己动手,光靠看书和上论坛是学不了编程的。

--changroc

个人觉得C只是一个工具。掌握工具就行了。更多的是软件系统架构的设计,硬件驱动接口,算法的设计。很多东西只需要有基础的C就能做。

--zgf

我的硬盘上也有这么个文件夹,以为是文件系统错误,一直没理,今天回去试试

--TEMP

不错,呵呵。

--绞肉机配件

漂亮

--Petroleum Machinery

不错,机箱后面一张MM张片不错-.-!

--快乐小胖鸟

漂亮。赞一个。小心EA找你收logo的版权费哦

--zgf的blog

电子邮件都是这个编码~

--玻璃小屋

恩。

--sjdev

跟进去单步运行一下,看看到哪步死的。我是xp+vs6环境

--hATEmATH

对不负责任的垃圾评论一律删无赦

--hATEmATH

不行啊,点击一下就死了,再指教一下

haibeike88@163.com

谢谢!

--海贝壳

谢谢,离吃喜糖还有一段时间呢,呵呵。

--hATEmATH

阅读排行榜

评论排行榜

随笔-127

文章-20

评论-453

Trackbacks-0

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

HateMath2005@163.com

关键词:Internet时间 同步时间 校时

转载请注明原创出处:HateMath的网上田园()

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

同步Internet时间,即通过Internet的校时网站传来的数据校准本机时间。但是现在网络上查到的相关编程资料并不多,且其中多是VB和Delphi的代码,VC的代码我还没找到过。是这个东西太难了?应该不是;是太简单了?那也总该有人写吧。

我认为,自己懂和让别人懂压根不是一回事,我写这篇文章,目的当然是后者。当然,理工科出身的河蚌不大可能像文科出身的河蚌那样修出光彩夺目的珍珠来,所以,行文有不妥之处,欢迎指正。校时原理:互联网上有很多时间服务器能够提供准确的时间,我们通过连接到这样的服务器来获取时间值。这里向大家介绍一下服务器传来的数据格式先。数据一共四个字节(4 Byte),我们可以在接收数据后对它进行“重新组装”,把组装所得的值放在一个32位的整数里,这个值的意义是:自1900年1月1日0时0分0秒 至 服务器发送这个时间数据时 所经历的秒数。显然,任何一个时刻到1900年所经历的秒数是唯一的,因此,由服务器传来的时间数据即可推出现在的时间,然后用API函数调整系统的时间即可。

流程图如下:

synctime_order.jpg

设计目标:

好了,我们的目标是:(没有蛀牙~)

-_-!!

常言说一图千言,我们还是看图吧:

SyncTime.JPG

程序的实现:

从技术角度来看,解决三个问题即可:1.通过网络通信从服务器获取时间数据。2.处理基于1900年的时间数据,转化为我们常见的时间形式。3.解决网络造成的延时问题。下面分条讲述:

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

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

代码片断:

None.gifCSocket sockClient;

None.gif    sockClient.Create();//创建socket

None.gif

None.gif//for debugNone.gifm_info+="Connect server:"+strServer+"dot.gif";

None.gif    UpdateData(FALSE);

None.gif//for debugNone.gifNone.gif    sockClient.Connect((LPCTSTR)strServer,37);//strServer:时间服务器网址; 37:端口号None.gifNone.gif    DWORD dwTime=0;//用来存放服务器传来的标准时间数据None.gifunsignedcharnTime[8];//临时接收数据None.gifmemset(nTime,0,sizeof(nTime));

None.gif

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

None.gif    

None.gif//for debugNone.gifm_info+="Connect shut down.";

None.gif    UpdateData(FALSE);

None.gif//for debugNone.gifNone.gif    dwTime+=nTime[0]<<24;//整合数据None.gifdwTime+=nTime[1]<<16;

None.gif    dwTime+=nTime[2]<<8;

None.gif    dwTime+=nTime[3];        

None.gif

None.gifif(0==dwTime)returnFALSE;

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

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

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

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

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

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

现场采访:这个时候,换了你,你会怎么办?

众人:◎#¥%#%……※……×※◎^&*(^*

错!应该去人气超强的VCKbase论坛!欢迎访问:

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

时间转换的方法如下:

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多资料,自己吐血先)

代码片断:

None.gif//服务器传来的数据是自从1900年以来的秒数

None.gif//取得 1900~1970 的时间差(以秒数计算) ,放在dwSpan里面None.gifCOleDateTime t00(1900,1,1,0,0,0);//1900.1.1 00:00:00None.gifCOleDateTime t70(1970,1,1,0,0,0);//1970.1.1 00:00:00None.gifNone.gif    COleDateTimeSpan ts70to00=t70-t00; 

None.gif    DWORD dwSpan=(DWORD)ts70to00.GetTotalSeconds(); 

None.gif    ASSERT( dwSpan==2208988800L); 

None.gif    

None.gif//把时间变为基于1970年的,便于用CTime处理None.gifdwTime-=dwSpan;        

None.gif//考虑网络延迟因素None.gifdwTime+=dwDely;

None.gif//构造当前时间的CTime对象None.gifCTime timeNow=(CTime)dwTime;

None.gif

None.gif//for debugNone.gifm_info+=timeNow.Format("%Y.%m.%d  %H:%M:%S");

None.gif    UpdateData(FALSE);

None.gif//for debug

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

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

演示程序及代码下载地址:

正文结束。

/*-----------------------------------

写后感:

1.对VCKbase论坛的网友的热忱帮助表示谢意。

2.关于时间基准的转换问题,如果还有新的办法,欢迎指教。

3.如果这篇文章稍加改动后给本站的在线杂志投稿,各位觉得发表的可能有多大?:-)

------------------------------------*/

posted on 2005-10-12 10:49 HateMath的网上田园 阅读(4567)

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

Posted @ 2005-10-12 11:23

完全可以发表:)稿费有吗?

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

Posted @ 2005-10-12 22:39

c++的代码很早就有了

原来我就用这个类在98下写过一个校时程序

还有 看了你的那个xp下vc校时的代码

如果只是纯粹的校时的话

这样更方便

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

Posted @ 2005-10-13 08:34

"整合数据"为什么不用ntohl?这样就平台无关了。

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

Posted @ 2005-10-13 08:45

你使用的VC++6.0打补丁VSSP6了没有,因为我发现debug目录中的synctime.exe在我这儿运行异常。

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

Posted @ 2005-10-13 18:33

to 星星 :

1)thanks,那样确实更方便.我的代码可以认为是给了另一种方法吧.

用ntohl涵数时,代码改为:

....

DWORD dwTime = 0;//用来存放服务器传来的标准时间数据

sockClient.Receive(&dwTime, sizeof(dwTime));//接收服务器发送来得4个字节的数据

dwTime = ntohl(dwTime);

if(0 == dwTime)return FALSE;

....

2)我也不知道打了SP6没有,我当时用的别人的机子......

不知道怎样才能看到打了没有呢?

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

Posted @ 2006-11-14 15:31

写得不错,加油了。哈哈

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

Posted @ 2007-05-20 13:51

呵呵,非常感谢楼主,从楼主的文章中学到很多,嘿嘿,看完后有个问题想请教下,要想在窗口中同时显示本机时间和实时输出服务器的时间该怎么办呢?

呵呵,再次表示感谢^-^

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

Posted @ 2007-06-06 18:51

to 小瑞:

完整意义上的实时输出服务器的时间恐怕有些困难,处于网络的限制你不可能更新的那么快的,除非用些小技巧。

--------------------next---------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值