可用的时间服务器地址如下:
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;
}