获得时间服务器的时间

// SyncTimeTest.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <WinSock2.h>
#include <Windows.h>
#include "DateTime.h"

FILE* g_logfile = stdout;

const char* szTimeServer[] = 
{
	"time-a.timefreq.bldrdoc.gov",
	"time-b.timefreq.bldrdoc.gov",
	"time-c.timefreq.bldrdoc.gov",
	"utcnist.colorado.edu",
	"time-nw.nist.gov",
	"nist1.nyc.certifiedtime.com",
	"nist1.dc.certifiedtime.com",
	"nist1.sjc.certifiedtime.com",
	"nist1.datum.com",
	"ntp2.cmc.ec.gc.ca",
	"ntps1-0.uni-erlangen.de",
	"ntps1-1.uni-erlangen.de",
	"ntps1-2.uni-erlangen.de",
	"ntps1-0.cs.tu-berlin.de",
	"time.ien.it",
	"ptbtime1.ptb.de",
	"ptbtime2.ptb.de"
};

//由主机名获得IP地址列表
int getsockaddrbyname(const char* name, struct in_addr* addrlist, int maxcount, int* preturncount)
{
	int count = 0;
	struct hostent* host = gethostbyname(name);
	if(host)
	{
		char **pptr;

	//	fprintf(g_logfile, "official hostname:%s\n",host->h_name);

	//	for(pptr = host->h_aliases; *pptr != NULL; pptr++)
	//		fprintf(g_logfile, " alias:%s\n",*pptr);

		switch(host->h_addrtype)
		{
		case AF_INET:
		case AF_INET6:
			for(pptr = host->h_addr_list; *pptr != NULL; pptr++)
			{
				memcpy(&addrlist[count++], *pptr, sizeof(struct in_addr));
				struct in_addr *inaddr = (struct in_addr *)(*pptr);
	//			fprintf(g_logfile, " address:%s\n", inet_ntoa(*inaddr));
			}
			break;
		default:
	//		fprintf(g_logfile, "unknown address type\n");
			break;
		}

		if(preturncount) *preturncount = count;
	}

	return count;
}

//获得时间服务器的时间
int getinternettime(const char* server, int port = 37, int timeout = 1000)
{
	int ret = 0;
	DateTime tmDate;
	long days_of_1900 = 0;
	int addr_count = 0;
	struct in_addr addr_list[32] = {0};

	fprintf(g_logfile, "[%s] \n", server);

	LoadDateStruct(&tmDate, 1900, 1, 1);
	days_of_1900 = DateToDayNumber(&tmDate);	//自1900年以来的天数

	if(getsockaddrbyname(server, addr_list, 32, &addr_count))
	{
		for(int i = 0; i < addr_count; i++)
		{
			struct sockaddr_in clientaddr;
			clientaddr.sin_family	= AF_INET;
			clientaddr.sin_addr		= addr_list[i];
			clientaddr.sin_port		= htons(port);

			SOCKET hsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
			if(INVALID_SOCKET != hsock)
			{
				setsockopt(hsock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));

				fprintf(g_logfile, "connect...\n");
				DWORD start = GetTickCount();
				if(connect(hsock, (struct sockaddr*)&clientaddr, sizeof(clientaddr)) == 0)
				{
					int recv_bytes = 0;
					DWORD dwTime = 0;						//用来存放服务器传来的标准时间数据
					unsigned char nTime[8] = {0};			//临时接收数据
					fprintf(g_logfile, "recv...\n");
					if((recv_bytes = recv(hsock, (char*)nTime, sizeof(nTime), 0)) > 0)
					{
						dwTime = (nTime[0] << 24) | (nTime[1] << 16) | (nTime[2] << 8) | nTime[3];			//整合数据	

						if(dwTime > 0)
						{
							dwTime += 8 * ONEHOUROFSECOND;		//UTC时间转换成北京时间, 加8小时

							//服务器传来的数据是自从1900年以来的秒数
							int second	= (dwTime % 60);
							int minute	= (dwTime / 60) % 60;
							int hour	= (dwTime / ONEHOUROFSECOND) % 24;
							int days	= (dwTime / ONEDAYOFSECONDS);

							DayNumberToDate(days_of_1900 + days, &tmDate);

							fprintf(g_logfile, "%04d-%02d-%02d %02d:%02d:%02d", 
								tmDate.wYear, tmDate.wMonth, tmDate.wDay, hour, minute, second);

							fprintf(g_logfile, "\t0x%X-0x%X-0x%X-0x%X", nTime[0], nTime[1], nTime[2], nTime[3]);

							if(tmDate.wYear != 2013 || tmDate.wMonth != 1 || tmDate.wDay != 7)
							{
								int k = 0;
							}

							ret = 1;
						}
					}
					else 
						fprintf(g_logfile, "recv bytes %d, error %d", recv_bytes, WSAGetLastError());
				}
				else
					fprintf(g_logfile, "connect error %d, timeout %dms", WSAGetLastError(), GetTickCount() - start);

				closesocket(hsock);
			}
		}
	}
	else
		fprintf(g_logfile, "gethostbyname error %d", WSAGetLastError());

	return ret;
}

int _tmain(int argc, _TCHAR* argv[])
{
	WSADATA wsd = {0};
	WSAStartup(MAKEWORD(2, 2), &wsd);

	g_logfile = fopen("\\ResidentFlash\\netclock_log.txt", "at");
	if(g_logfile == NULL)
		g_logfile = stdout;

	while(1)
	{
		fprintf(g_logfile, "-----------------------------------------------------------\n");
		int count = sizeof(szTimeServer) / sizeof(szTimeServer[0]);
		for(int i = 0; i < count; i++)
		{
			if(getinternettime(szTimeServer[i]))
				fprintf(g_logfile, " \t OK\n");
			else
				fprintf(g_logfile, " \t FAIL\n");
			fprintf(g_logfile, "\n");
		}
	}

	if(g_logfile && g_logfile != stdout)
		fclose(g_logfile);

	WSACleanup();

	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值