从时间服务同步本地时间

可用的时间服务器地址如下:

ntp.sjtu.edu.cn 202.120.2.101 (上海交通大学网络中心NTP服务器地址)

s1a.time.edu.cn 北京邮电大学

s1b.time.edu.cn 清华大学

s1c.time.edu.cn 北京大学

s1d.time.edu.cn 东南大学

s1e.time.edu.cn 清华大学

s2a.time.edu.cn 清华大学

s2b.time.edu.cn 清华大学

s2c.time.edu.cn 北京邮电大学

s2d.time.edu.cn 西南地区网络中心

s2e.time.edu.cn 西北地区网络中心

s2f.time.edu.cn 东北地区网络中心

s2g.time.edu.cn 华东南地区网络中心

s2h.time.edu.cn 四川大学网络管理中心

s2j.time.edu.cn 大连理工大学网络中心

s2k.time.edu.cn CERNET桂林主节点

s2m.time.edu.cn 北京大学

代码如下:

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

#include "stdafx.h"
#include <time.h>
#include <winsock2.h>
#pragma comment(lib, "WS2_32")

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;     
};

enum E_RESULT
{
	InitSocketFailed,			// socket库初始化失败
	SocketNotVersion2,			// socket版本不是2
	RequestSendFailed,			// 发送请求失败
	ResponseRecvFailed,			// 响应请求失败
	GetServerTimeFailed,		// 获取服务器时间失败
	GetServerTimeSuccessed		// 获取服务器时间成功
};

E_RESULT UpdateSysTime();

int _tmain(int argc, _TCHAR* argv[])
{
	E_RESULT eResult = UpdateSysTime();
	switch (eResult)
	{
	case InitSocketFailed:
		printf("socket库初始化失败\n");
		break;
	case SocketNotVersion2:
		printf("socket版本不对\n");
		break;
	case RequestSendFailed:
		printf("发送请求失败\n");
		break;
	case ResponseRecvFailed:
		printf("响应请求失败\n");
		break;
	case GetServerTimeFailed:
		printf("获取服务器时间失败\n");
		break;
	case GetServerTimeSuccessed:
		printf("获取服务器时间成功\n");
		break;
	}

	system("pause");

	return 0;
}

E_RESULT UpdateSysTime()  
{  
	unsigned short    wVersionRequested;  
	WSADATA wsaData;  

	// 初始化版本  
	wVersionRequested = MAKEWORD( 2, 2 );  
	if (0!=WSAStartup(wVersionRequested, &wsaData))   
	{  
		WSACleanup();  
		return InitSocketFailed;  
	}  
	if (LOBYTE(wsaData.wVersion)!=2 || HIBYTE(wsaData.wVersion)!=2)   
	{  
		WSACleanup( );  
		return SocketNotVersion2;   
	}  

	// 这个IP是中国大陆时间同步服务器地址,可自行修改  
	SOCKET soc=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);  
	struct sockaddr_in addrSrv;  
	addrSrv.sin_addr.S_un.S_addr=inet_addr("s2b.time.edu.cn");  // 上海交通大学网络中心NTP服务器地址(网上找的)
	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 RequestSendFailed;  
	}  
	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 ResponseRecvFailed;  
	}  
	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 GetServerTimeFailed;  
	}  

	// 获取新的时间  
	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;  

	//printf("开始校正时间\n");
	// 修改本机系统时间  
	SetLocalTime(&newtime);  
	//printf("校正时间成功\n");
	return GetServerTimeSuccessed;  
}  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值