获取网络时间并刷新本地时间(源码1)

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <TCHAR.H>
#include <winsock.h>
#pragma comment (lib,"Ws2_32")


#define UNICODE
#define _UNICODE

#define _countof(array) (sizeof(array)/sizeof(array[0]))
#define HIGHTIME		21968699 // 21968708 // Jan 1, 1900 FILETIME.highTime
#define LOWTIME			4259332096 // 1604626432 // Jan 1, 1900 FILETIME.lowtime

using namespace std;

//NTP服务器列表
struct NISTSVR{
	int     key;	//编号
	in_addr addr;	//IP地址
	LPCTSTR server;	//域名
	LPCTSTR info;	//信息
} NISTSVRSARY[] = {
	{ 0, {0,0,0,0}, NULL, NULL},
	{ 1, {129,6,15,28}, _T("time-a.nist.gov"),_T("NIST,盖士堡,马里兰州") },
	{ 2, {129,6,15,29}, _T("time-b.nist.gov"),_T("NIST,盖士堡,马里兰州") },
	{ 3, {132,163,4,101}, _T("time-a.timefreq.bldrdoc.gov"),_T("NIST,博耳德市,科罗拉多州") },
	{ 4, {132,163,4,102}, _T("time-b.timefreq.bldrdoc.gov"),_T("NIST,博耳德市,科罗拉多州") },
	{ 5, {132,163,4,103}, _T("time-c.timefreq.bldrdoc.gov"),_T("NIST,博耳德市,科罗拉多州") },
	{ 6, {128,138,140,44}, _T("tutcnist.colorado.edu"),_T("科罗拉多大学,博耳德市") },
	{ 7, {192,43,244,18}, _T("time.nist.gov"),_T("NCAR,博耳德市,科罗拉多州") },
	{ 8, {131,107,1,10}, _T("time-nw.nist.gov"),_T("Microsoft,雷蒙德,华盛顿州") },
	{ 9, {208,184,49,129}, _T("nist1.nyc.certifiedtime.com"),_T("Abovnet,纽约市") },
};

//所选择的NTP服务器
static int choice = 0;

void usage()
{
	printf( "\n\t----------------------------------------------\n" );
	printf( "\t=*= Time Getter v1.0 \t([email protected]) =*=\n" );
	printf( "\t----------------------------------------------\n\n" );

	int l = _countof(NISTSVRSARY);
	for (int i= 1; i< l; i++){
		printf("    %d. %s [%s] %s \r\n", NISTSVRSARY[i].key, NISTSVRSARY[i].server, 
			inet_ntoa(NISTSVRSARY[i].addr), NISTSVRSARY[i].info);
	}
}

BOOL UpdateSysTime(DWORD dwTime)
{
	UINT64 uiCurTime, uiBaseTime, uiResult;
	SYSTEMTIME st = {0};

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

	uiCurTime = (UINT64)dwTime * (UINT64)10000000;
	uiResult = uiBaseTime + uiCurTime;

	FileTimeToSystemTime((LPFILETIME)&uiResult, &st);
	
	return SetSystemTime(&st);
}

BOOL GetTimeFromServer(DWORD *lpdwTime)
{
	*lpdwTime = 0;
	BOOL bReturn= FALSE;

	SOCKET sSock = socket(AF_INET, SOCK_STREAM, 0);
	if(INVALID_SOCKET != sSock)
	{
		struct sockaddr_in sin;

		memcpy(&sin.sin_addr, &NISTSVRSARY[choice].addr, sizeof(in_addr));
		sin.sin_family = AF_INET;
		sin.sin_port = htons(IPPORT_TIMESERVER);
	
		printf( "\n    ...Waiting Connection...\n");

		if(0 == connect(sSock, (struct sockaddr *) &sin, sizeof(struct sockaddr_in)))
		{
			printf( "    ***Connected***\n");
			int iResult, iRead;

			for(iRead = 0; iRead < 4; iRead += iResult)
			{
				iResult = recv(sSock, (char*)lpdwTime + iRead, 4 - iRead, 0);
				if(iResult < 1)
					break;
			}

			if(4 == iRead)
			{
				*lpdwTime = ntohl(*lpdwTime);

				bReturn = TRUE;
			}else
				printf( "    Error getting time!\n");
		}else
			printf( "    ***Connection Failed***\n");


		closesocket(sSock);
	}

	return bReturn;
}

int main(int argc,char *argv[])
{
	WSADATA WSAData;
	if(WSAStartup (MAKEWORD(1,1), &WSAData) != 0)
	{
           printf("WSAStartup failed.\n");
           WSACleanup();
           exit(1);
    }

    if(argc<2)
	{
		usage();
		while (choice <= 0 || choice > 9) cin>>choice;
	}else 
		choice = atoi(&argv[1][strlen(argv[1])-1]);
	
	DWORD dwTime;
	//取服务器时间
	if (GetTimeFromServer(&dwTime))
	{
		//更新系统时间
		if (UpdateSysTime(dwTime))
		{
			printf( "    ***System Clock Successfully Updated***\n");
		}else{
			printf( "    ***Error setting the System Clock***\n");
		}
	}

	WSACleanup();
	
	return 0;
}

以上代码来源与网络。亲测可用。

注:设置本地时间或许不重要,但获取网络时间是很重的,比如发布一个程序,限制使用者使用到期时间,这个时候我们可以获取网络时间,如果是获取本地时间的话就很容易被别人更改本地时间从而跳出限制,获取网络时间就相对安全一点。

猜你喜欢

转载自blog.csdn.net/liujiayu2/article/details/83057507