客户机怎么访问服务器时间与服务器时间怎么查询

2004年4月 总版技术专家分月排行榜第二
2006年1月 Delphi大版内专家分月排行榜第一2005年12月 Delphi大版内专家分月排行榜第一2005年11月 Delphi大版内专家分月排行榜第一2005年10月 Delphi大版内专家分月排行榜第一2005年6月 Delphi大版内专家分月排行榜第一2004年10月 Delphi大版内专家分月排行榜第一2004年9月 Delphi大版内专家分月排行榜第一2004年8月 Delphi大版内专家分月排行榜第一2004年7月 Delphi大版内专家分月排行榜第一2004年6月 Delphi大版内专家分月排行榜第一2004年5月 Delphi大版内专家分月排行榜第一2004年4月 Delphi大版内专家分月排行榜第一2004年3月 Delphi大版内专家分月排行榜第一2003年12月 Delphi大版内专家分月排行榜第一2003年11月 Delphi大版内专家分月排行榜第一
2009年7月 荣获微软MVP称号2010年7月 荣获微软MVP称号2008年7月 荣获微软MVP称号
2005年2月 Delphi大版内专家分月排行榜第一
2004年4月 总版技术专家分月排行榜第二
2006年1月 Delphi大版内专家分月排行榜第一2005年12月 Delphi大版内专家分月排行榜第一2005年11月 Delphi大版内专家分月排行榜第一2005年10月 Delphi大版内专家分月排行榜第一2005年6月 Delphi大版内专家分月排行榜第一2004年10月 Delphi大版内专家分月排行榜第一2004年9月 Delphi大版内专家分月排行榜第一2004年8月 Delphi大版内专家分月排行榜第一2004年7月 Delphi大版内专家分月排行榜第一2004年6月 Delphi大版内专家分月排行榜第一2004年5月 Delphi大版内专家分月排行榜第一2004年4月 Delphi大版内专家分月排行榜第一2004年3月 Delphi大版内专家分月排行榜第一2003年12月 Delphi大版内专家分月排行榜第一2003年11月 Delphi大版内专家分月排行榜第一
本帖子已过去太久远了,不再提供回复功能。怎样设置服务器与客户端时间同步
我的图书馆
怎样设置服务器与客户端时间同步
一 域环境,默认情况下,所有计算机都会和域控制器同步时间的,无需特别设置。二 工作组环境1)如果所有机器都可以访问internet,可以直接使用(默认的配置)2)如果机器不能访问internet,或者有防火墙导致无法同步,可以在2003服务器上创建时间服务器,客户端XP系统设置时间服务器地址为2003服务器。三 客户端设置双击托盘区显示时间的地方,出现对话框之后选择Internet时间设置时间服务器的地址。默认为,设置为2003服务器地址,然后单击“立即更新”按钮实现“时间同步”。四 服务器端设置1. 单击“开始”,单击“运行”,键入 regedit,然后单击“确定”。2. 找到并单击下面的注册表子项:&&&&& HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\Config\AnnounceFlags3. 在右窗格中,右键单击“AnnounceFlags”,然后单击“修改”。4. 在“编辑 DWORD 值”的“数值数据”框中键入 A,然后单击“确定”。5. 退出注册表编辑器。6. 在命令提示符处,键入以下命令以重新启动 Windows 时间服务,然后按 Enter:&&&&& net stop w32time && net start w32time最近因工作原因,需要客户端计算机与FTP服务器时间上进行同步,上网搜集了些时间同步的方法记录下来, 以备不需之用!
1.时间协议(TIME protocol) &&& 时间协议(TIME protocol)是一个在RFC 868内定义的网络协议。它用作提供机器可读的日期时间资讯。&&& 时间协议可以在TCP或UDP上使用。在TCP上,主机会连接支援时间协议的服务器的TCP埠 37。服务器会传送32位二进制数字然后断开连接,数字表示由格林威治时间日午夜0时0分0秒至当时的总秒数。主机在接收到时间后断开连接。&&& 在UDP上,客户端会每送一个(通常为空的)数据包到UDP埠 37。服务器会把包含时间的数据包传回。在过程中没有进行连线。&&& 现时,时间协议已经被网络时间协议(Network Time Protocol,NTP)所取代。&&& &&& 使用时间协议需要在服务器端开启时间服务,目前在windows中我还没找到系统自带的开启时间服务的方法, 但网络上有些小软件可以帮助实现(如NetTime网络时标, 它支持Time,NTP等好几种协议, 可惜需要注册使用).&&& &&& 基于时间协议客户端实现代码:
view plaincopy to clipboardprint?01.void SetLocalSystemTime(u_long ulTime)&& 02.{&& 03.&&& FILETIME&&&&& ftN&&&&&&& 04.&&& SYSTEMTIME&&& stOld, stN&&&&&&& 05.&&& ::GetLocalTime (&stOld) ;&& //首先取得目前的本地时间&& 06.&&& stNew.wYear&&&&&&&& = 1900 ;&& 07.&&& stNew.wMonth&&&&&&& = 1 ;&& 08.&&& stNew.wDay&&&&&&&&& = 1 ;&& 09.&&& stNew.wHour&&&&&&&& = 0 ;&& 10.&&& stNew.wMinute&&&&&& = 0 ;&& 11.&&& stNew.wSecond&&&&&& = 0 ;&& 12.&&& stNew.wMilliseconds = 0 ;&& 13.&&& ::SystemTimeToFileTime (&stNew, &ftNew);&& 14.&&& /*& 将SYSTEMTIME结构设定为日午夜(0时)。& 15.&&& 并将这个SYSTEMTIME结构传递给SystemTimeToFileTime,将此结构转化为FILETIME结构。& 16.&&& FILETIME实际上只是由两个32位元的DWORD一起组成64位元的整数,& 17.&&& 用来表示从日至今间隔为100奈秒(nanosecond)的间隔数。 */&&&&&&& 18.&&& LARGE_INTEGER&&&&&&&&& //64位大整数&& 19.&&& li = * (LARGE_INTEGER *) &ftN&& 20.&&& li.QuadPart += (LONGLONG)
* ulT&&& 21.&&& ftNew = * (FILETIME *) &&& 22.&&& ::FileTimeToSystemTime (&ftNew, &stNew);&& 23.&&& ::SetSystemTime (&stNew);&& 24.}&& 25.bool SetSystemFromSocket(LPCSTR lpRemote)&& 26.{&& 27.&&& bool ret =&& 28.&&& WSADATA WSAD&& 29.&&& ::WSAStartup (MAKEWORD(2,2), &WSAData);&&& 30.&&& SOCKET skt=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);&& 31.&&& TCHAR msg[512];&& 32.&&& if (skt == INVALID_SOCKET)&& 33.&&& {&& 34.&&&&&&& goto END;&& 35.&&& }&& 36.&&& struct sockaddr_&& 37.&&& sa.sin_family = AF_INET ;&& 38.&&& sa.sin_port = ::htons (IPPORT_TIMESERVER) ;&& //#define IPPORT_TIMESERVER&&& 37&& 39.&&& sa.sin_addr.S_un.S_addr = ::inet_addr(lpRemote) ;&& 40.&&& if (sa.sin_addr.S_un.S_addr == INADDR_NONE)&& 41.&&& {&& 42.&&&&&&& HOSTENT* host = gethostbyname(lpRemote);&& 43.&&&&&&& if (NULL == host)&& 44.&&&&&&& {&& 45.&&&&&&&&&&& goto END;&& 46.&&&&&&& }&& 47.&&&&&&& sa.sin_addr.S_un.S_addr = *(u_long *)host-&h_addr_list[0];&& 48.&&& }&& 49.&&& if(::connect(skt, (SOCKADDR*) &sa, sizeof(sa)) == SOCKET_ERROR)&& 50.&&& {&& 51.&&&&&&& goto END;&& 52.&&& }&& 53.&&& int iR&& 54.&&& u_long ulT&& 55.&&& iResult = recv(skt, (char*)&ulTime, 4, 0);&& 56.&&& //同步????&& 57.&&& if ( iResult&0 )&& 58.&&& {&& 59.&&&&&&& ulTime = ::ntohl(ulTime);&& 60.&&&&&&& SetLocalSystemTime(ulTime);&& 61.&&& }&& 62.END:&& 63.&&& closesocket(skt);&& 64.&&& ::WSACleanup();&& 65.&&&&& 66.}& void SetLocalSystemTime(u_long ulTime){&FILETIME&&&&& ftN&&&& &SYSTEMTIME&&& stOld, stN&&&& &::GetLocalTime (&stOld) ;&& //首先取得目前的本地时间&stNew.wYear&&&&&&&& = 1900 ;&stNew.wMonth&&&&&&& = 1 ;&stNew.wDay&&&&&&&&& = 1 ;&stNew.wHour&&&&&&&& = 0 ;&stNew.wMinute&&&&&& = 0 ;&stNew.wSecond&&&&&& = 0 ;&stNew.wMilliseconds = 0 ;&::SystemTimeToFileTime (&stNew, &ftNew);&/*& 将SYSTEMTIME结构设定为日午夜(0时)。&并将这个SYSTEMTIME结构传递给SystemTimeToFileTime,将此结构转化为FILETIME结构。&FILETIME实际上只是由两个32位元的DWORD一起组成64位元的整数,&用来表示从日至今间隔为100奈秒(nanosecond)的间隔数。 */&&&& &LARGE_INTEGER&&&//64位大整数&li = * (LARGE_INTEGER *) &ftN&li.QuadPart += (LONGLONG)
* ulT &ftNew = * (FILETIME *) &&::FileTimeToSystemTime (&ftNew, &stNew);&::SetSystemTime (&stNew);}bool SetSystemFromSocket(LPCSTR lpRemote){&bool ret =&WSADATA WSAD&::WSAStartup (MAKEWORD(2,2), &WSAData);&&SOCKET skt=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);&TCHAR msg[512];&if (skt == INVALID_SOCKET)&{&&goto END;&}&struct sockaddr_&sa.sin_family = AF_INET ;&sa.sin_port = ::htons (IPPORT_TIMESERVER) ;&& //#define IPPORT_TIMESERVER&&& 37&sa.sin_addr.S_un.S_addr = ::inet_addr(lpRemote) ;&if (sa.sin_addr.S_un.S_addr == INADDR_NONE)&{&&HOSTENT* host = gethostbyname(lpRemote);&&if (NULL == host)&&{&&&goto END;&&}&&sa.sin_addr.S_un.S_addr = *(u_long *)host-&h_addr_list[0];&}&if(::connect(skt, (SOCKADDR*) &sa, sizeof(sa)) == SOCKET_ERROR)&{&&goto END;&}&int iR&u_long ulT&iResult = recv(skt, (char*)&ulTime, 4, 0);&//同步????&if ( iResult&0 )&{&&ulTime = ::ntohl(ulTime);&&SetLocalSystemTime(ulTime);&}END:&closesocket(skt);&::WSACleanup();&}&
2.网络校时协议(NTP) &&& Network Time Protocol(NTP)是用来使计算机时间同步化的一种协议,它可以使计算机对其服务器或时钟源(如石英钟,GPS等等
)做同步化,它可以提供高精准度的时间校正(LAN上与标准间差小于1毫秒,WAN上几十毫秒),且可介由加密确认的方式来防止恶毒的
协议攻击。&&& NTP协议格式:&&& NTP packet = NTP header + Four TimeStamps = 48byte
&&& NTP header : 16byte&&& +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
&&& |LI | VN |Mode | Stratum | Poll | Precision |&&& +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-&&& LeapYearIndicator : 2bit&&& VersionNumber : 3bit&&& Stratum : 8bit&&& Mode : 3 bit&&& PollInterval : 8 bit&&& Percision : 8bit
&&& | Root Delay |&&& +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-&&& Root delay : 32bit
&&& | Root Dispersion |&&& +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-&&& Root Dispersion : 32bit
&&& | Reference Identifier |&&& +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-&&& Reference Identifier : 32bit
&&& Four TimeStamps : 32byte&&& +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
&&& | Reference Timestamp |&&& +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-&&& Reference Timestamp : 64bit
&&& | Originate Timestamp |&&& +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-&&& Originate Timestamp : 64bit
&&& | Receive Timestamp |&&& +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-&&& Receive Timestamp : 64bit
&&& | Transmit Timestamp |&&& +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-&&& Transmit Timestamp : 64bit
&&& | Authenticator (optional) (96) |&&& +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
&&& * LI:跳跃指示器,警告在当月最后一天的最终时刻插入的迫近闺秒(闺秒)。&&& * VN:版本号。&&& * Mode:模式。该字段包括以下值:0-预留;1-对称行为;3-客户机;4-服务器;5-广播;6-NTP 控制信息&&& * Stratum:对本地时钟级别的整体识别。&&& * Poll:有符号整数表示连续信息间的最大间隔。&&& * Precision:有符号整数表示本地时钟精确度。&&& * Root Delay:有符号固定点序号表示主要参考源的总延迟,很短时间内的位15到16间的分段点。&&& * Root Dispersion:无符号固定点序号表示相对于主要参考源的正常差错,很短时间内的位15到16间的分段点。&&& * Reference Identifier:识别特殊参考源。&&& * Originate Timestamp:这是向服务器请求分离客户机的时间,采用64位时标(Timestamp)格式。&&& * Receive Timestamp:这是向服务器请求到达客户机的时间,采用64位时标(Timestamp)格式。&&& * Transmit Timestamp:这是向客户机答复分离服务器的时间,采用64位时标(Timestamp)格式。&&& * Authenticator(Optional):当实现了 NTP 认证模式,主要标识符和信息数字域就包括已定义的信息认证代码(MAC)信息。
&&& 配置NTP服务器:&&& 1)、Linux主机做时间服务器(以RedHat9.0为例)&&& 第一步:检查是否已经***有ntp软件包。输入“rpm -qa|grep ntp”,如果已经***应该显示“ntp-4.1.2-0.rc1”。  第二步:***ntp软件,从下载rpm包,输入“rpm -ivh ntp-xxx.rpm”执行***。  第三步:配置ntp服务。备份原/etc/ntp.conf文件后,输入以下内容    server pool.ntp.org&&& server pool.ntp.org&&& server pool.ntp.org&&& driftfile /etc/ntp/drift&&& 三行server都设pool.ntp.org是为了提供连接冗余,当第一个地址连接失败时,后面的地址提供时间服务,注意这里的
pool.ntp.org对应一组IP地址,由DNS随机分配。  第四步:启动ntp服务。输入“service ntp restart”。  为了保证以后Linux机启动后ntp服务能自动启动,还要输入“chkconfig ntpd on”。Linux下的ntp软件不但能自动与互联网上的时钟
保持同步,同时本身已经是一台SNTP服务器了,可以供局域网内的电脑校对时间。建议启动 NTP服务后,先用date命令手工校正一下时
间,以后系统会自动与互联网上的主时间服务器保持同步。ntp服务还有一个好处,如果当前系统的时间与标准时间有所误差,它不是马
上把时间校正,而是逐步缩小与标准时间的误差,以免系统内部出现时间突变。
&&& 2)、Windows2000、XP做时间服务器  第一步:指定主时间服务器。在DOS方式输入“net time /setsntp:pool.ntp.org”,这里我们指定pool.ntp.org是主时间服务器,也
可以是其它地址。  第二步:开始与主时间服务器同步。先关闭windows time服务,再开启该服务。可以在“管理工具”的“服务”界面下完成,也可以以
DOS方式输入“net stop w32time”、“net start w32time”。  第三步:设置电脑的Windows time服务的启动方式为自动。在“管理工具”的“服务”界面下完成。  注意这台windows主机不能加入任何域,否则无法启动windows time服务。此时,这台windows电脑已经是互联上主时间服务器的客
户了,以后每次电脑启动时,都会自动与主时间服务器校对时间。如果网络不通,电脑也会过45分钟后再次自动校对时间。需要注意的
是电脑的时钟与标准时间误差不能超过12小时,否则不能自动校对,而要手动校正了。  第四步:使这台电脑成为时间服务器,供局域网内部的电脑校对时间。用“regedit”打开注册表,把
“HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesW32TimeParameters”中的 LocalNTP改为1即可。
&&& 3)、Windows98做时间服务器  一般不推荐Windows98系统做时间服务器,而且win98本身也不含时间服务器功能,需要***第三方软件。
&&& 客户端时间同步代码:
view plaincopy to clipboardprint?01.#include &Windows.h&&& 02.#include &stdlib.h&&& 03.#include &Winsock2.h&&& 04.#include &time.h&&& 05.#pragma comment(lib, "Ws2_32.lib")&& 06.typedef struct ntp {&& 07.&&& char F&& 08.&&& char PeerClockS&& 09.&&& char PeerPollingI&& 10.&&& char PeerClockP&&& 11.&&& char RootDelay[4];&& 12.&&& char ClockDispersion[4];&& 13.&&& char ReferenceClock[4];&& 14.&&& char ReferenceClockUpdateTime[8];&& 15.&&& char OriginateTimeStamp[8];&& 16.&&& char ReceiveTimeStamp[8];&& 17.&&& char TransmitTimeStamp[8];&& 18.} tagNTP;&& 19.BOOL SetNewTime(WORD year,WORD month,WORD day,WORD hour, WORD minutes,WORD second)&& 20.{&& 21.&&& SYSTEMTIME&& 22.&&& GetSystemTime(&st);&& 23.&&& st.wYear=year+1900;&&&&&&&& //调整日期和时间&& 24.&&& st.wMonth=month+1;&& 25.&&& st.wDay =&& 26.&&& st.wHour =&&& 27.&&& st.wMinute =&& 28.&&& st.wSecond =&&& 29.&&& if (!SetLocalTime(&st))&&& 30.&&&&&&& return FALSE;&& 31.&&& return TRUE;&& 32.}&& 33.void main()&& 34.{&& 35.&&& WSADATA wsaD&& 36.&&& SOCKET SendS&& 37.&&& sockaddr_in RecvA&& 38.&&& //Receive Data&& 39.&&& sockaddr_in SenderA&& 40.&&& int SenderAddrSize = sizeof(SenderAddr);&& 41.&&& ntp SendB&& 42.&&& int Port = IPPORT_NTP;&&&&&&&&& //#define IPPORT_NTP 123&& 43.&&& //以下变量的赋值均来源于NTP数据包,你可以用Ethereal抓包&& 44.&&& SendBuf.Flag =0x1b;&& 45.&&& SendBuf.PeerClockStratum =0x00;&& 46.&&& SendBuf.PeerPollingInterval =0x00;&& 47.&&& SendBuf.PeerClockPrecision =0x00;&& 48.&&& memset(SendBuf.RootDelay ,0,4);&& 49.&&& memset(SendBuf.ClockDispersion,0,4);&& 50.&&& memset(SendBuf.ReferenceClock,0,4);&& 51.&&& memset(SendBuf.ReferenceClockUpdateTime,0,8);&&& 52.&&& memset(SendBuf.OriginateTimeStamp,0,8);&& 53.&&& memset(SendBuf.ReceiveTimeStamp,0,8);&& 54.&&& memcpy(&SendBuf.TransmitTimeStamp[0],"0xc7",1);&& 55.&&& memcpy(&SendBuf.TransmitTimeStamp[1],"0x50",1);&& 56.&&& memcpy(&SendBuf.TransmitTimeStamp[2],"0xe7",1);&& 57.&&& memcpy(&SendBuf.TransmitTimeStamp[3],"0xa0",1);&& 58.&&& SendBuf.TransmitTimeStamp[4]=0x00;&& 59.&&& SendBuf.TransmitTimeStamp[5]=0x00;&& 60.&&& SendBuf.TransmitTimeStamp[6]=0x00;&& 61.&&& SendBuf.TransmitTimeStamp[7]=0x00;&& 62.&&& int BufLen = 48; //包的长度为48字节&& 63.&&& tm *&& 64.&&& time_t long_&& 65.&&& WSAStartup(MAKEWORD(2,2), &wsaData);&& 66.&&& //---------------------------------------------&& 67.&&& // Create a socket for sending data&& 68.&&& SendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);&& 69.&&& RecvAddr.sin_family = AF_INET;&& 70.&&& RecvAddr.sin_port = htons(Port);&& 71.&&& RecvAddr.sin_addr.s_addr = inet_addr("128.101.1.241");& //NTP服务器的地址&& 72.&&& sendto(SendSocket,&& 73.&&&&&&& (char *)&SendBuf,&& 74.&&&&&&& BufLen,&& 75.&&&&&&& 0,&& 76.&&&&&&& (SOCKADDR *) &RecvAddr,&& 77.&&&&&&& sizeof(RecvAddr));&& 78.&&& /*开始接收发过来的数据*/& 79.&&& printf("Receiving datagrams...\n");&& 80.&&& recvfrom(SendSocket,&& 81.&&&&&&& (char *)&SendBuf,&& 82.&&&&&&& BufLen,&& 83.&&&&&&& 0,&& 84.&&&&&&& (SOCKADDR *)&SenderAddr,&& 85.&&&&&&& &SenderAddrSize);&& 86.&&& printf("Finished receiving.Closing socket.\n");&& 87.&&& closesocket(SendSocket);&& 88.&&& //*********************************************&& 89.&&& memcpy(&long_time,SendBuf.ReceiveTimeStamp,4);& //从收到的包里面取出前32位放入变量long_time中&& 90.&&&&&&& printf("%d\n",long_time);&& 91.&&& long_time = ntohl(long_time)-;//把低位的字节和高位字节互换&& 92.&&& newtime = localtime(&long_time); /* Convert to local time. */&& 93.&&& SetNewTime(newtime-&tm_year,&& 94.&&& newtime-&tm_mon ,&& 95.&&& newtime-&tm_mday ,&& 96.&&& newtime-&tm_hour ,&& 97.&&& newtime-&tm_min,&& 98.&&& newtime-&tm_sec );&& 99.&&& //---------------------------------------------&& 100.&&& // Clean up and quit.&& 101.&&& //---------------------------------------------&& 102.&&& printf("OK,Exiting.\n");&& 103.&&& WSACleanup();&& 104.&&&&& 105.}&& #include &Windows.h&#include &stdlib.h&#include &Winsock2.h&#include &time.h&#pragma comment(lib, "Ws2_32.lib")typedef struct ntp {&char F&char PeerClockS&char PeerPollingI&char PeerClockP &char RootDelay[4];&char ClockDispersion[4];&char ReferenceClock[4];&char ReferenceClockUpdateTime[8];&char OriginateTimeStamp[8];&char ReceiveTimeStamp[8];&char TransmitTimeStamp[8];} tagNTP;BOOL SetNewTime(WORD year,WORD month,WORD day,WORD hour, WORD minutes,WORD second){&SYSTEMTIME&GetSystemTime(&st);&st.wYear=year+1900; &&//调整日期和时间&st.wMonth=month+1;&st.wDay =&st.wHour =&&st.wMinute =&st.wSecond = &if (!SetLocalTime(&st)) &&return FALSE;&return TRUE;}void main(){&WSADATA wsaD&SOCKET SendS&sockaddr_in RecvA&//Receive Data&sockaddr_in SenderA&int SenderAddrSize = sizeof(SenderAddr);&ntp SendB&int Port = IPPORT_NTP;&&&//#define IPPORT_NTP 123&//以下变量的赋值均来源于NTP数据包,你可以用Ethereal抓包&SendBuf.Flag =0x1b;&SendBuf.PeerClockStratum =0x00;&SendBuf.PeerPollingInterval =0x00;&SendBuf.PeerClockPrecision =0x00;&memset(SendBuf.RootDelay ,0,4);&memset(SendBuf.ClockDispersion,0,4);&memset(SendBuf.ReferenceClock,0,4);&memset(SendBuf.ReferenceClockUpdateTime,0,8); &memset(SendBuf.OriginateTimeStamp,0,8);&memset(SendBuf.ReceiveTimeStamp,0,8);&memcpy(&SendBuf.TransmitTimeStamp[0],"0xc7",1);&memcpy(&SendBuf.TransmitTimeStamp[1],"0x50",1);&memcpy(&SendBuf.TransmitTimeStamp[2],"0xe7",1);&memcpy(&SendBuf.TransmitTimeStamp[3],"0xa0",1);&SendBuf.TransmitTimeStamp[4]=0x00;&SendBuf.TransmitTimeStamp[5]=0x00;&SendBuf.TransmitTimeStamp[6]=0x00;&SendBuf.TransmitTimeStamp[7]=0x00;&int BufLen = 48; //包的长度为48字节&tm *&time_t long_&WSAStartup(MAKEWORD(2,2), &wsaData);&//---------------------------------------------&// Create a socket for sending data&SendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);&RecvAddr.sin_family = AF_INET;&RecvAddr.sin_port = htons(Port);&RecvAddr.sin_addr.s_addr = inet_addr("128.101.1.241");&//NTP服务器的地址&sendto(SendSocket,&&(char *)&SendBuf,&&BufLen,&&0,&&(SOCKADDR *) &RecvAddr,&&sizeof(RecvAddr));&/*开始接收发过来的数据*/&printf("Receiving datagrams...\n");&recvfrom(SendSocket,&&(char *)&SendBuf,&&BufLen,&&0,&&(SOCKADDR *)&SenderAddr,&&&SenderAddrSize);&printf("Finished receiving.Closing socket.\n");&closesocket(SendSocket);&//*********************************************&memcpy(&long_time,SendBuf.ReceiveTimeStamp,4);&//从收到的包里面取出前32位放入变量long_time中&&printf("%d\n",long_time);&long_time = ntohl(long_time)-;//把低位的字节和高位字节互换&newtime = localtime(&long_time); /* Convert to local time. */&SetNewTime(newtime-&tm_year,&newtime-&tm_mon ,&newtime-&tm_mday ,&newtime-&tm_hour ,&newtime-&tm_min,&newtime-&tm_sec );&//---------------------------------------------&// Clean up and quit.&//---------------------------------------------&printf("OK,Exiting.\n");&WSACleanup();&}&
3.NetRemoteTOD API函数
&&& NetRemoteTOD可以返回指定服务器的时间,具体说明见MSDN.&&& 利用这个API函数有个限制,那就是客户端必须要有对服务器的访问权限(你可以先通过局域网访问这台服务器,然后记住访问密码,
再用这个函数访问就不会有问题了),否则函数会返回权限拒绝错误.&&& NetRemoteTOD示例:
view plaincopy to clipboardprint?01.#include &stdio.h&&& 02.#include &windows.h&&&& 03.#include &lm.h&&& 04.int wmain(int argc, wchar_t *argv[])&& 05.{&& 06.&& LPTIME_OF_DAY_INFO pBuf = NULL;&& 07.&& NET_API_STATUS nS&& 08.&& LPTSTR pszServerName = NULL;&& 09.&& if (argc & 2)&& 10.&& {&& 11.&&&&& fwprintf(stderr, L"Usage: %s [\\\\ServerName]\n", argv[0]);&& 12.&&&&& exit(1);&& 13.&& }&& 14.&& // The server is not the default local computer.&& 15.&& //&& 16.&& if (argc == 2)&& 17.&&&&& pszServerName = argv[1];&& 18.&& //&& 19.&& // Call the NetRemoteTOD function.&& 20.&& //&& 21.&& nStatus = NetRemoteTOD(pszServerName,&& 22.&&&&&&&&&&&&&&&&&&&&&&&&& (LPBYTE *)&pBuf);&& 23.&& //&& 24.&& // If the function succeeds, display the current date and time.&& 25.&& //&& 26.&& if (nStatus == NERR_Success)&& 27.&& {&& 28.&&&&& if (pBuf != NULL)&& 29.&&&&& {&& 30.&&&&&&&& fprintf(stderr, "\nThe current date is: %d/%d/%d\n",&& 31.&&&&&&&&&&&&&&&& pBuf-&tod_month, pBuf-&tod_day, pBuf-&tod_year);&& 32.&&&&&&&& fprintf(stderr, "The current time is: %d:%d:%d\n",&& 33.&&&&&&&&&&&&&&&& pBuf-&tod_hours, pBuf-&tod_mins, pBuf-&tod_secs);&& 34.&&&&& }&& 35.&& }&& 36.&& //&& 37.&& // Otherwise, display a system error.&& 38.&& else& 39.&&&&& fprintf(stderr, "A system error has occurred: %d\n", nStatus);&& 40.&& //&& 41.&& // Free the allocated buffer.&& 42.&& //&& 43.&& if (pBuf != NULL)&& 44.&&&&& NetApiBufferFree(pBuf);&& 45.&& return 0;&& 46.}& #include &stdio.h&#include &windows.h& #include &lm.h&int wmain(int argc, wchar_t *argv[]){&& LPTIME_OF_DAY_INFO pBuf = NULL;&& NET_API_STATUS nS&& LPTSTR pszServerName = NULL;&& if (argc & 2)&& {&&&&& fwprintf(stderr, L"Usage: %s [\\\\ServerName]\n", argv[0]);&&&&& exit(1);&& }&& // The server is not the default local computer.&& //&& if (argc == 2)&&&&& pszServerName = argv[1];&& //&& // Call the NetRemoteTOD function.&& //&& nStatus = NetRemoteTOD(pszServerName,&&&&&&&&&&&&&&&&&&&&&&&&& (LPBYTE *)&pBuf);&& //&& // If the function succeeds, display the current date and time.&& //&& if (nStatus == NERR_Success)&& {&&&&& if (pBuf != NULL)&&&&& {&&&&&&&& fprintf(stderr, "\nThe current date is: %d/%d/%d\n",&&&&&&&&&&&&&&&& pBuf-&tod_month, pBuf-&tod_day, pBuf-&tod_year);&&&&&&&& fprintf(stderr, "The current time is: %d:%d:%d\n",&&&&&&&&&&&&&&&& pBuf-&tod_hours, pBuf-&tod_mins, pBuf-&tod_secs);&&&&& }&& }&& //&& // Otherwise, display a system error.&& else&&&&& fprintf(stderr, "A system error has occurred: %d\n", nStatus);&& //&& // Free the allocated buffer.&& //&& if (pBuf != NULL)&&&&& NetApiBufferFree(pBuf);&& return 0;}
4.其他方法 &&& 如果条件允许的话,我们可以自己写服务器端程式来返回需要的服务器端时间,然后在客户端写socket来接收时间信息.&&& 还有一种更简单的方法就是向服务器上写一个文件,然后读取这个文件的创建日期来获得服务器的时间,这种方法可能精确性不是很高,而且需要对服务器有写文件的权限
本文来自CSDN博客,转载请标明出处:
TA的最新馆藏[转]&[转]&[转]&[转]&[转]&[转]&

参考资料

 

随机推荐