根据时间服务器校正系统时间-对时

本程序用于校正本机时间
http://blog.csdn.net/qq752923276/article/details/7591198
以下是使用方法
1、默认方式,使用默认时间服务器时间校正本机时间
2、命令行附加一个时间服务器IP参数,将根据指定时间服务器时间校正本机时间,如:timecalibration.exe 132.163.4.102 

代码:

// timecalibration.cpp : Defines the entry point for the console application.
//
/************************************************************************/
/* http://blog.csdn.net/qq752923276/article/details/7591198             */
/************************************************************************/
#include "stdafx.h"
#include <WinSock2.h>
#include <windows.h>
#include <cstdio>
#include <cassert>

#pragma comment(lib,"ws2_32.lib")

class InitSocket
{
public:
	InitSocket()
	{
		WSADATA wsaData={0};
		assert(::WSAStartup(MAKEWORD(2,2),&wsaData)==0);
	}
	~InitSocket()
	{
		::WSACleanup();
	}
};
InitSocket initsocket;
/************************************************************************/
/*		 timesrv:
		 132.163.4.101
		 132.163.4.102
		 132.163.4.103													*/
/************************************************************************/
char szIP[32]="132.163.4.101";

bool SetTime(DWORD tm)
{
	FILETIME      ft={0};     
	SYSTEMTIME    stTM={0};     
	stTM.wYear         = 1900 ;
	stTM.wMonth        = 1 ;
	stTM.wDay          = 1 ;
	::SystemTimeToFileTime (&stTM, &ft);   
	
	LARGE_INTEGER li ;			//64位大整数
	li = * (LARGE_INTEGER *) &ft;
	li.QuadPart += (LONGLONG) 10000000 * tm; 
	
	ft = * (FILETIME *) &li;
	::FileTimeToSystemTime (&ft, &stTM);
	return ::SetSystemTime (&stTM)==TRUE;
}
BOOL SetConsoleColor(WORD wAttributes)  
{  
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);  
    if (hConsole == INVALID_HANDLE_VALUE)  
        return FALSE;  
	
    return SetConsoleTextAttribute(hConsole, wAttributes);  
}  
int main(int argc, char* argv[])
{
	assert(SetConsoleColor( FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_INTENSITY));
	do
	{
		if(argc==1)
		{
			puts("本程序用于校正本机时间");
			puts("http://blog.csdn.net/qq752923276\r\n");   
			puts("以下是使用方法");
			puts("1、默认方式,使用默认时间服务器时间校正本机时间");
			puts("2、命令行附加一个时间服务器IP参数,将根据指定时间服务器时间校正本机时间,\r\n如:timecalibration.exe 132.163.4.102 ");
			puts("\r\n按任意键继续...");
			getchar();
			goto start;
		}
		else if(argc==2)
		{
			memcpy(szIP,argv[1],lstrlen(argv[1]));
			
start:
			SOCKADDR_IN addr;
			addr.sin_addr.S_un.S_addr=inet_addr(szIP);
			if(addr.sin_addr.S_un.S_addr==0xffffffff)
			{
				puts("非法的IP的地址");
				break;
			}
			addr.sin_family=AF_INET;
			addr.sin_port=::htons(IPPORT_TIMESERVER);

			SOCKET sClient=::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
			assert(sClient);
			__try
			{
				DWORD dwset=1;  
				int ret=::ioctlsocket(sClient,FIONBIO,(LPDWORD)&dwset);  
				if (ret==SOCKET_ERROR)  
				{  
					break; 
				}   
				::connect(sClient,(SOCKADDR*)&addr,sizeof addr);  
				
				timeval timeout;  
				fd_set r;  
				FD_ZERO(&r);  
				FD_SET(sClient,&r);  
				timeout.tv_sec=1;  
				timeout.tv_usec=0;  
				
				ret=::select(0,0,&r,0,&timeout);  
				if (ret<=0) //超时或SOCKET_ERROR  
				{  
					puts("连接超时");  
					break;
				}  
				else  
				{
					puts("连接成功!");
					
					fd_set readset;
					FD_ZERO(&readset);  
					FD_SET(sClient,&readset);  
					timeout.tv_sec=1;  
					timeout.tv_usec=0;
					ret=::select(0,&readset,0,0,&timeout);
					if(ret>0)
					{
						DWORD tm=0;
						int ret=::recv(sClient, (char *) &tm, sizeof tm, 0);
						if(ret==sizeof tm)
						{
							tm=::ntohl(tm);
							if (SetTime(tm))
							{
								puts("校正系统时间成功!");
							}
							else
								puts("设置系统时间失败!");
						}
						else
							puts("接收失败!");
					}
					else
					{
						puts("接收超时");
					}
				}  
			}
			__finally
			{
			  closesocket(sClient);
			}
		}
	}while(0);
	puts("\r\n按任意键退出...");
	getchar();
	return 0;
}

另,根据中国授时中心校准时间(NTP协议):

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
#include <time.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
//---------------------------------------------------------------------------

#pragma argsused

struct   NTP_Packet{ /*传送数据的结构体*/ 
 int   Control_Word; 
 int   root_delay; 
 int   root_dispersion; 
 int   reference_identifier; 
 __int64   reference_timestamp; 
 __int64   originate_timestamp; 
 __int64   receive_timestamp; 
 int   transmit_timestamp_seconds; 
 int   transmit_timestamp_fractions; 
};
BOOL SetTime()
{
    WORD    wVersionRequested;
    WSADATA wsaData;
    
    // 初始化版本
    wVersionRequested = MAKEWORD( 1, 1 );
    if (0!=WSAStartup(wVersionRequested, &wsaData)) 
    {
        WSACleanup();
        return FALSE;
    }
    if (LOBYTE(wsaData.wVersion)!=1 || HIBYTE(wsaData.wVersion)!=1) 
    {
        WSACleanup( );
        return FALSE; 
    }
    
    // 这个IP是中国大陆时间同步服务器地址,可自行修改
 // 中国国家授时中心的IP地址是:210.72.145.44
    SOCKET soc = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    struct sockaddr_in addrSrv;
    addrSrv.sin_addr.S_un.S_addr=inet_addr("210.72.145.44");
// addrSrv.sin_addr.S_un.S_addr=inet_addr("time-a.timefreq.bldrdoc.gov");
    addrSrv.sin_family=AF_INET;
    addrSrv.sin_port=htons(123);
    
    NTP_Packet NTP_Send, NTP_Recv; 
    NTP_Send.Control_Word   =   htonl(0x0B000000);   
    NTP_Send.root_delay        =   0;   
    NTP_Send.root_dispersion   =   0;   
    NTP_Send.reference_identifier    =   0;   
    NTP_Send.reference_timestamp    =   0;   
    NTP_Send.originate_timestamp    =   0;   
    NTP_Send.receive_timestamp        =   0;   
    NTP_Send.transmit_timestamp_seconds        =   0;   
    NTP_Send.transmit_timestamp_fractions   =   0; 
    
    if(SOCKET_ERROR==sendto(soc,(const char*)&NTP_Send,sizeof(NTP_Send),
        0,(struct sockaddr*)&addrSrv,sizeof(addrSrv)))
    {
        closesocket(soc);
        return FALSE;
    }
    int sockaddr_Size =sizeof(addrSrv);
    if(SOCKET_ERROR==recvfrom(soc,(char*)&NTP_Recv,sizeof(NTP_Recv),
        0,(struct sockaddr*)&addrSrv,&sockaddr_Size))
    {
        closesocket(soc);
        return FALSE;
    }
    closesocket(soc);
    WSACleanup();
    
    SYSTEMTIME    newtime;
    float        Splitseconds;
    struct        tm    *lpLocalTime;
    time_t        ntp_time;
    
    // 获取时间服务器的时间
    ntp_time    = ntohl(NTP_Recv.transmit_timestamp_seconds)-2208988800;
    lpLocalTime = localtime(&ntp_time);
    if(lpLocalTime == NULL)
    {
        return FALSE;
    }
    
    // 获取新的时间
    newtime.wYear      =lpLocalTime->tm_year+1900;
    newtime.wMonth     =lpLocalTime->tm_mon+1;
    newtime.wDayOfWeek =lpLocalTime->tm_wday;
    newtime.wDay       =lpLocalTime->tm_mday;
    newtime.wHour      =lpLocalTime->tm_hour;
    newtime.wMinute    =lpLocalTime->tm_min;
    newtime.wSecond    =lpLocalTime->tm_sec;
    
    // 设置时间精度
    Splitseconds=(float)ntohl(NTP_Recv.transmit_timestamp_fractions);
    Splitseconds=(float)0.000000000200 * Splitseconds;
    Splitseconds=(float)1000.0 * Splitseconds;
    newtime.wMilliseconds   =   (unsigned   short)Splitseconds;
    
    // 修改本机系统时间
    SetLocalTime(&newtime);
    return TRUE;
}
int main(int argc, char* argv[])
{
        SetTime();
        return 0;
}
//---------------------------------------------------------------------------
 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值