查看完整版本: 一个VC写的时间校验器

乌鸦 2007-11-14 13:25

一个VC写的时间校验器

大家编译的时候需要WSOCK库文件的,你可以按以下方法添加:
project->settings->link->object/library modules: 添加WSOCK32.LIB ws2_32.lib

//代码
#include <stdio.h>
#include "winsock2.h"
#include <time.h>

//******************************//
// 定义一个结构,就是NTP包的结构//
//******************************//
typedef struct ntp {
char Flag;
char PeerClockStratum;
char PeerPollingInterval;
char PeerClockPrecision;
char RootDelay[4];
char ClockDispersion[4];
char ReferenceClock[4];
char ReferenceClockUpdateTime[8];
char OriginateTimeStamp[8];
char ReceiveTimeStamp[8];
char TransmitTimeStamp[8];
} tagNTP;

//*********************************************************//
// 定义一个函数,设置操作系统时间的函数 //
// SetNewTime - sets system time //
// Return value - TRUE if successful, FALSE otherwise //
// hour - new hour (0-23) //
// minutes - new minutes (0-59) //
// Author:白色猎人 [Unicorn QQ:233536605] //
//*********************************************************//
BOOL SetNewTime(WORD year,WORD month,WORD day,WORD hour, WORD minutes,WORD second)
{
SYSTEMTIME st;

GetSystemTime(&st); // gets current time
st.wYear=year+1900; // adjusts year
st.wMonth=month+1; // adjusts month
st.wDay =day; // adjusts day
st.wHour =hour; // adjusts hours
st.wMinute =minutes; // and minutes
st.wSecond =second; // and second
if (!SetLocalTime(&st)) // sets system time
return FALSE;
return TRUE;
}

void main()
{
WSADATA wsaData;
SOCKET SendSocket;
sockaddr_in RecvAddr;
//Receive Data
sockaddr_in SenderAddr;
int SenderAddrSize = sizeof(SenderAddr);

ntp SendBuf;
int Port = 123; //NTP端口为:123

//以下变量的赋值均来源于NTP数据包,你可以用Ethereal抓包
SendBuf.Flag =0x1b;
SendBuf.PeerClockStratum =0x00;
SendBuf.PeerPollingInterval =0x00;
SendBuf.PeerClockPrecision =0x00;
memset(SendBuf.RootDelay ,0,4);
memset(SendBuf.ClockDispersion,0,4);
memset(SendBuf.ReferenceClock,0,4);
memset(SendBuf.ReferenceClockUpdateTime,0,8);
memset(SendBuf.OriginateTimeStamp,0,8);
memset(SendBuf.ReceiveTimeStamp,0,8);
memcpy(&SendBuf.TransmitTimeStamp[0],"0xc7",1);
memcpy(&SendBuf.TransmitTimeStamp[1],"0x50",1);
memcpy(&SendBuf.TransmitTimeStamp[2],"0xe7",1);
memcpy(&SendBuf.TransmitTimeStamp[3],"0xa0",1);
SendBuf.TransmitTimeStamp[4]=0x00;
SendBuf.TransmitTimeStamp[5]=0x00;
SendBuf.TransmitTimeStamp[6]=0x00;
SendBuf.TransmitTimeStamp[7]=0x00;

int BufLen = 48; //包的长度为48字节

tm *newtime;
time_t long_time;
//---------------------------------------------
// Initialize Winsock
WSAStartup(MAKEWORD(2,2), &wsaData);

//---------------------------------------------
// Create a socket for sending data
SendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

//---------------------------------------------
// Set up the RecvAddr structure with the IP address of
// the receiver (in this example case "123.456.789.1")
// and the specified port number.
RecvAddr.sin_family = AF_INET;
RecvAddr.sin_port = htons(Port);
RecvAddr.sin_addr.s_addr = inet_addr("207.46.130.100"); //207.46.130.100NTP服务器的地址

//---------------------------------------------
// Send a datagram to the receiver
printf("Sending a datagram to the receiver...\n");
sendto(SendSocket,
(char *)&SendBuf,
BufLen,
0,
(SOCKADDR *) &RecvAddr,
sizeof(RecvAddr));

printf("Finished sending.\n");

/*开始接收发过来的数据*/
printf("Receiving datagrams...\n");
recvfrom(SendSocket,
(char *)&SendBuf,
BufLen,
0,
(SOCKADDR *)&SenderAddr,
&SenderAddrSize);
printf("Finished receiving.Closing socket.\n");
closesocket(SendSocket);
//*********************************************
memcpy(&long_time,SendBuf.ReceiveTimeStamp,4); //从收到的包里面取出前32位放入变量long_time中
printf("%d\n",long_time);

long_time = ntohl(long_time)-2208988800; //把低位的字节和高位字节互换

newtime = localtime(&long_time); /* Convert to local time. */
SetNewTime(newtime->tm_year,
newtime->tm_mon ,
newtime->tm_mday ,
newtime->tm_hour ,
newtime->tm_min,
newtime->tm_sec );
//---------------------------------------------
// Clean up and quit.
//---------------------------------------------
printf("OK,Exiting.\n");
WSACleanup();
return;
}

以下是我网上找到的NTP协议的资料(大家有兴趣可以参考下):

NTP:网络时间协议
NTP:Network Time Protocol

  网络时间协议(NTP)是一种通过因特网服务于计算机时钟的时间同步协议。它提供了一种同步时间机制,能在龐大而复杂多样的因特网中用光速调整时间分配。它使用的是可返回时间设计,分布式子网内的时间服务器,能自我组织操作、分层管理配置,经过有线或无线方式同步子网内的逻辑时钟达到国家标准时间。此外,通过本地路由选择运算法则及时间后台程序,服务器可以重新分配标准时间。

  NTP 的设计带来了三种产品——时钟偏移、时间延迟及差量,它们都与指定参考时钟相关联。时钟偏移表示调整本地时钟与参考时钟相一致而产生的偏差数;时间延迟表示在指定时间内发送消息到达参考时钟的延时时间;差量表示了相对于参考时钟本地时钟的最大偏差错误。因为大多数主机时间服务器通过其它对等时间服务器达到同步,所以这三种产品中的每一种都有两个组成部分:其一是由对等决定的部分,这部分是相对于原始标准时间的参考来源而言;其二是由主机衡量的部分,这部分是相对于对等而言。每一部分在协议中都是独立维持的,从而可以使错误控制和子网本身的管理操作变得容易。它们不仅提供了偏移和延迟的精密测量,而且提供了明确的最大错误范围,这样用户接口不但可以决定时间,而且可以决定时间的准确度。

  NTP 源于时间协议和 ICMP 时间标志消息,但其设计更强调精确度和健壮性两个方面,即使是在有多路网关、延迟差量及不可靠网络上使用时。当前使用的最新版是 NTPv3 ,它与以前的版本兼容。


协议结构:

2 5 8 16 24 32bit
LI VN Mode Stratum Poll Precision
Root Delay
Root Dispersion
Reference Identifier
Reference timestamp(64)
Originate Timestamp(64)
Receive Timestamp(64)
Transmit Timestamp(64)
Key Identifier(optional)(32)
Message digest(optional)(128)

LI:跳跃指示器,警告在当月最后一天的最终时刻插入的迫近闺秒(闺秒)。

VN:版本号。

Mode:模式。该字段包括以下值:0-预留;1-对称行为;3-客户机;4-服务器;5-广播;6-NTP 控制信息

Stratum:对本地时钟级别的整体识别。

Poll:有符号整数表示连续信息间的最大间隔。

Precision:有符号整数表示本地时钟精确度。

Root Delay:有符号固定点序号表示主要参考源的总延迟,很短时间内的位15到16间的分段点。

Root Dispersion:无符号固定点序号表示相对于主要参考源的正常差错,很短时间内的位15到16间的分段点。

Reference Identifier:识别特殊参考源。

Originate Timestamp:这是向服务器请求分离客户机的时间,采用64位时标(Timestamp)格式。

Receive Timestamp:这是向服务器请求到达客户机的时间, 采用64位时标(Timestamp)格式。

Transmit Timestamp:这是向客户机答复分离服务器的时间,采用64位时标(Timestamp)格式。

Authenticator(Optional):当实现了 NTP 认证模式,主要标识符和信息数字域就包括已定义的信息认证代码(MAC)信息。
页: [1]
查看完整版本: 一个VC写的时间校验器