|
本帖最后由 xiaoyigechaos 于 2014-11-9 15:26 编辑
先来个NTP协议介绍
http://blog.163.com/yzc_5001/blog/static/2061963420121283050787/
关于时间戳的换算工具
http://tool.chinaz.com/Tools/unixtime.aspx#
下面是代码,C-Free + MinGW 编译,须在工程连接参数里添加 -lwsock32
- #include <stdio.h>
- #include <time.h>
- #include <winsock2.h>
- #define JAN_1970 0x83AA7E80 /* 2208988800 1970-1900 in seconds*/
- typedef union
- {
- int time;
- char time_array[4];
- } Timestamp;
- typedef struct
- {
- char message_hdr[16];//报文头部
- char RefTimestamp[8];
- Timestamp T1;
- char T1_decimal[4]; //T1的小数部分
- Timestamp T2;
- char T2_decimal[4]; //T2的小数部分
- Timestamp T3;
- char T3_decimal[4]; //T3的小数部分
- } NTP_MESSAGE;
- int main()
- {
- WORD socketVersion = MAKEWORD(2,2);
- WSADATA wsaData;
- if(WSAStartup(socketVersion, &wsaData) != 0)
- {
- return 0;
- }
- SOCKET sclient = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-
- SOCKADDR_IN sin;
- sin.sin_family = AF_INET;
- sin.sin_port = htons(123);
- sin.sin_addr.S_un.S_addr = inet_addr("198.123.30.132");
- int len = sizeof(sin);
-
- char sendData[] = { //构造报文
- 0x1B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD0, 0xAF, 0x5F, 0xF5, 0x23, 0xD7, 0x08, 0x00
- };
-
- printf("Connect to NTP Server...\n");
-
- time_t T1=time(NULL);
-
- sendto(sclient, sendData, sizeof(sendData), 0, (SOCKADDR *)&sin, len);
- char recvData[48]={0};
- int ret = recvfrom(sclient, recvData, 48, 0, (SOCKADDR *)&sin, &len);
- if(ret > 0)
- {
- time_t T4=time(NULL);
-
- printf("Connect success!\n\n");
- printf("Now the local time is %s",ctime(&T4));
-
- NTP_MESSAGE *ntp_time=(NTP_MESSAGE *)recvData;
-
- /* 大小端变换 由于NTP以1900为始,需变换 */
- ntp_time->T2.time=ntohl(ntp_time->T2.time)-JAN_1970;//T2
- ntp_time->T3.time=ntohl(ntp_time->T3.time)-JAN_1970;//T3
-
- /* NTP报文的网络延时=(T4-T1)-(T3-T2) */
- time_t net_delay=(T4-T1)-(ntp_time->T3.time-ntp_time->T2.time);
- printf("Net delay is %ld second(s).\n",net_delay);
-
- /* 误差补偿秒数=((T2-T1)+(T3-T4))/2 */
- time_t Deviation=(((time_t)ntp_time->T2.time-T1)+((time_t)ntp_time->T3.time-T4))/2;
- printf("\nThe deviation is %d second(s).\n",Deviation);
-
- if(Deviation != 0)
- {
- printf("Reset the local time...\n");
-
- time_t now=time(NULL)+Deviation;
- struct tm *ptr;
- ptr=localtime(&now);
- char buffer[20]={0};
-
- sprintf(buffer,"date %d-%d-%d",ptr->tm_year+1900,ptr->tm_mon+1,ptr->tm_mday);
- system(buffer);
-
- sprintf(buffer,"time %d:%d:%d",ptr->tm_hour,ptr->tm_min,ptr->tm_sec);
- system(buffer);
- now=time(NULL);
- printf("Now the local time is %s",ctime(&now));
- }
- else //没有误差,无需校时
- {
- printf("Here is no need to set local time.\n");
- }
- }
- closesocket(sclient);
- WSACleanup();
- system("pause");
- return 0;
- }
复制代码
由于使用API 设置时间在 win7 下需要特殊的权限,故采用系统命令 date 和 time 设置,算是 不是办法的办法。
关于NTP协议,最开始给出的链接有具体的说明,在程序中,只需48个字节的必须内容即可,其它内容属可选项。
时间的小数部分抛弃不用,对于一般校时而言足够了。
下面给个截图
![](http://ww4.sinaimg.cn/large/44083984jw1em4rxrzx6gj20it0cajt0.jpg) |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|