用C语言实现的在线对时器

2012-04-29 11:33丁元
科技资讯 2012年29期
关键词:缓冲区C语言字符

丁元

摘要:利用Internet传送标准时间信息称做网络授时。目前网上有很多授时服务器,我们可以用高级语言写一个在线对时器,获取授时服务器上的时间并以此来校对本机时间。本文以C语言为工具,实现了一个简单的在线对时器的开发。

关键词:C语言 在线对时

中图分类号:TP302 文献标识码:A 文章编号:1672-3791(2012)10(b)-0006-01

在线对时器的作用是从Internet上获取准确的时间。它的基本设计思想是开发出客户端工具,以此登录到网络上的授时服务器并获取它的准确时间,然后根据这个时间来校对本机的系统时间。下面以C语言为开发工具,介绍一种简单的在线定时器的实现方法。

1 登录到授时服务器

Internet上可用的授时服务器很多,这里采用香港的官方授时服务器(IP地址:210.0.235.14)。

核心代码如下。

//初始化套接字

SOCKETsock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

SOCKADDR_INsa;

sa.sin_family=AF_INET;

//设置套接字连接服务器端的端口(客户端端口由套接字动态分配,无需指定)

sa.sin_port=htons(IPPORT_TIMESERVER);//IPPORT_TIMESERVER是宏,对应的

//值是37,它代表TIMESERVER的端口号

//设置要连接到的授时服务器的IP地址

sa.sin_addr.S_un.S_addr=inet_addr("210.0.235.14");

//指定了端口号和IP地址之后,开始登录到授时服务器

connect(sock,(SOCKADDR*)&sa,sizeof(sa));

2 接收授时服务器传过来的信息

我们这里采用的授时服务器,返回给客户端的是1900年1月1日0点0分0秒到现在的秒数,是整型数字。而我们将要使用的接收服务器返回的消息的recv函数,它相应的参数是字符指针类型,因此需要进行类型转换,这在代码中将得到体现。具体如下。

//定义用来接收返回的时间秒数的变量

unsignedlongulTime=0;

//使用recv函数接收以秒数代表的当前时间

recv(sock,(char*)&ulTime,sizeof(unsignedlong),0);

那么这个秒数是多少呢?我们可以将它打印出来看一下:

//定义字符缓冲区

TCHARbuff[256];

//将缓冲区清零

ZeroMemory(buff,sizeof(buff)/sizeof(TCHAR));

将接收的秒数写到定义的缓冲区中

wsprintf(buff,"%i",ulTime);

//以对话框的形式显示接收的秒数

MessageBox(NULL,buff,TEXT("以秒数代表的当前时间"),MB_OK);

我们得到的对话框如图1所示。

为什么得到的结果明显不对呢?这涉及到字节顺序的问题,也就是说我们的客户机存储的整数的字节顺序和授时服务器不一致,导致传过来的ulTime没有得到正确的还原。这个问题很好解决,我们在将ulTime写到缓冲区之前,使用ntohl函数对ulTime做个处理即可(ulTime=ntohl(ulTime))。

3 将秒数表示的时间转换为字符形式的时间

下面我们要将上面得到的一串数字转换为我们看得懂的字符形式的时间,我们用以下代码实现。

SYSTEMTIMEst;

UINT64uiCurTime,uiBaseTime,uiResult;

uiBaseTime=((UINT64)HIGHTIME<<32)+LOWTIME;

uiCurTime=(UINT64)ulTime*(UINT64)10000000;

uiResult=uiBaseTime+uiCurTime;

FileTimeToSystemTime((LPFILETIME)&uiResult,&st);

以上代码将接收到的以ulTime代表的秒数转换为了st这个结构体变量所代表的字符形式的时间(st中包含了年、月、日、时、分、秒的信息)。

我们将st中的内容打印出来看一下,用以下代码实现。

TCHARbuff[256];

ZeroMemory(buff,sizeof(buff)/sizeof(TCHAR));

wsprintf(buff,TEXT("%i年%i月%i日%i:%i:%i"),st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond);//中国时区在东八区,因此在小时上加8;

MessageBox(NULL,buff,TEXT("字符形式的时间"),MB_OK);

打印出来的结果如图2所示。

为什么得到的小时不对呢?很简单,中国在东八区,应该在小时上加上8,也就是将st.wHour改为st.wHour+8。

4 将得到的时间设成本机系统时间

经过以上的测试,我们已经得到了授时服务器上的准确时间。将这个时间设置成本地系统时间即可,代码只需一句。

SetSystemTime(&st);//将st这个结构体变量所对应的时间赋给本机。

5 结语

本文介绍了用C语言实现的在线对时器开发的基本思路和核心代码。用其它高级语言开发在线对时器的基本方法与此类似。希望这样的客户端工具的开发,对于想深入学习网络编程的朋友,能起到一个铺垫的作用。

参考文献

[1] 谭浩强.C程序设计[M].清华大学出版社,1999.

[2] 佩措尔德.Windows程序设计[M].清华大学出版社,2010.

猜你喜欢
缓冲区C语言字符
嵌入式系统环形缓冲区快速读写方法的设计与实现
寻找更强的字符映射管理器
基于Visual Studio Code的C语言程序设计实践教学探索
字符代表几
一种USB接口字符液晶控制器设计
消失的殖民村庄和神秘字符
基于C语言的计算机软件编程
高职高专院校C语言程序设计教学改革探索
关键链技术缓冲区的确定方法研究
论子函数在C语言数据格式输出中的应用