概述Windows中的基本NTP客户端在Visual C ++中
美好的一天,
背景:我几乎完全使用C,汇编和shell脚本。 一般来说,我很less使用C ++,JAVA或OOdevise。
我正在尝试实现一个非常基本的NTP客户端,以便我可以查询远程NTP服务器(即: pool.ntp.org )的Internet时间,以便在每次启动时自动设置windows开发板上的时间。
我从另一个用户在这里重构了代码:
我怎么能告诉我的机器上的每个核心使用相同的计时器?
time()和gettimeofday()之间的区别以及为什么会导致seg错误
将UTC tm *转换为本地化tm *的跨平台方法?
如何在linux下测量C程序的ACTUAL执行时间?
什么是CLOCK_TAI的时代?
用sntp从服务器获取时间/date(windows c ++)
但程序挂在recv() *** 作。 DNSparsing和send() *** 作似乎执行没有任何问题。
有谁知道我在哪里可以find一个简单的windows NTP客户端示例(GPL是首选,但任何事情都可以在这一点上),或者他们可以评论为什么下面的代码块会挂起这个例子(我不应该说“挂起“,它似乎从来没有收到回应)。
NTP_CLIENT.CPP
/****************************************************************************** * Project headers *****************************************************************************/ #include \”stdafx.h\” #include \”ntp_clIEnt.h\” /****************************************************************************** * System headers *****************************************************************************/ #include <winsock2.h> #include <winsock.h> #include <ws2tcpip.h> /****************************************************************************** * Preprocessor Directives and Macros *****************************************************************************/ /****************************************************************************** * Class Member Function DeFinitions *****************************************************************************/ voID Timestamp::ReverseEndian(voID) { ReverseEndianInt(seconds); ReverseEndianInt(fraction); } time_t Timestamp::to_time_t(voID) { return (seconds – ((70 * 365 + 17) * 86400))&0x7fffffff; } voID NTPMessage::ReverseEndian(voID) { ref.ReverseEndian(); orig.ReverseEndian(); rx.ReverseEndian(); tx.ReverseEndian(); } int NTPMessage::recv(int sock) { int ret = ::recv(sock,(char*)this,sizeof(*this),0); ReverseEndian(); return ret; } int NTPMessage::sendto(int sock,struct sockaddr_in* srv_addr) { ReverseEndian(); int ret = ::sendto(sock,(const char*)this,(sockaddr*)srv_addr,sizeof(*srv_addr)); ReverseEndian(); return ret; } voID NTPMessage::clear() { memset(this,sizeof(*this)); }
NTP_CLIENT.H
#ifndef __NTP_CLIENT_H__ #define __NTP_CLIENT_H__ #include <ctime> #define ReverseEndianInt(x) ((x) = ((x)&0xff000000) >> 24 | ((x)&0x00ff0000) >> 8 | ((x)&0x0000ff00) << 8 | ((x)&0x000000ff) << 24) /** * NTP Fixed-Point Timestamp Format. * From [RFC 5905](http://tools.IEtf.org/HTML/rfc5905). */ struct Timestamp { unsigned int seconds; /**< Seconds since Jan 1,1900. */ unsigned int fraction; /**< Fractional part of seconds. Integer number of 2^-32 seconds. */ /** * Reverses the Endianness of the timestamp. * Network byte order is big endian,so it needs to be switched before * sending or reading. */ voID ReverseEndian(voID); /** * Convert to time_t. * Returns the integer part of the timestamp in unix time_t format,* which is seconds since Jan 1,1970. */ time_t to_time_t(voID); }; /** * A Network Time Protocol Message. * From [RFC 5905](http://tools.IEtf.org/HTML/rfc5905). */ struct NTPMessage { unsigned int mode :3; /**< Mode of the message sender. 3 = ClIEnt,4 = Server */ unsigned int version :2; /**< Protocol version. Should be set to 3. */ unsigned int leap :2; /**< Leap seconds warning. See the [RFC](http://tools.IEtf.org/HTML/rfc5905#section-7.3) */ unsigned char stratum; /**< Servers between clIEnt and physical timekeeper. 1 = Server is Connected to Physical Source. 0 = UnkNown. */ unsigned char poll; /**< Max Poll Rate. In log2 seconds. */ unsigned char precision; /**< Precision of the clock. In log2 seconds. */ unsigned int sync_distance; /**< Round-trip to reference clock. NTP Short Format. */ unsigned int drift_rate; /**< dispersion to reference clock. NTP Short Format. */ unsigned char ref_clock_ID[4]; /**< Reference ID. For Stratum 1 devices,a 4-byte string. For other devices,4-byte IP address. */ Timestamp ref; /**< Reference Timestamp. The time when the system clock was last updated. */ Timestamp orig; /**< Origin Timestamp. Send time of the request. copIEd from the request. */ Timestamp rx; /**< RecIEve Timestamp. RecIEpt time of the request. */ Timestamp tx; /**< Transmit Timestamp. Send time of the response. If only a single time is needed,use this one. */ /** * Reverses the Endianness of all the timestamps. * Network byte order is big endian,so they need to be switched before * sending and after reading. * * Maintaining them in little endian makes them easIEr to work with * locally,though. */ voID ReverseEndian(voID); /** * RecIEve an NTPMessage. * Overwrites this object with values from the received packet. */ int recv(int sock); /** * Send an NTPMessage. */ int sendto(int sock,struct sockaddr_in* srv_addr); /** * Zero all the values. */ voID clear(); }; #endif /* __NTP_CLIENT_H__ */
被测设备上的防火墙和防病毒软件已被禁用。
谢谢。
编辑
按要求,这是主体的main :
WSADATA wsaData; DWORD ret = WSAStartup(MAKEWORD(2,0),&wsaData); char *host = \”pool.ntp.org\”; /* Don\’t distribute stuff pointing here,it\’s not polite. */ //char *host = \”time.nist.gov\”; /* This one\’s probably ok,but can get grumpy about request rates during deBUGging. */ NTPMessage msg; /* important,if you don\’t set the version/mode,the server will ignore you. */ msg.clear(); msg.version = 3; msg.mode = 3 /* clIEnt */; NTPMessage response; response.clear(); int sock = socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP); sockaddr_in srv_addr; memset(&srv_addr,sizeof(srv_addr)); dns_lookup(host,&srv_addr); /* Helper function defined below. */ msg.sendto(sock,&srv_addr); response.recv(sock); time_t t = response.tx.to_time_t(); char *s = ctime(&t); printf(\”The time is %s.\”,s); WSACleanup();
参考
用sntp从服务器获取时间/date(windows c ++)
如何在不使用ls -ln的情况下在C中打印文件详细信息
是否有另一个精确的计时器time.clock()在windows上?
getcpuTime只返回两个值(0或15625000000) – 这是正确的吗?
一个timepec在tv_nsec字段中可以有超过1秒的纳秒时间吗?
为什么时间的纳秒值:持续时间在windows上最接近100的倍数?
从RFC 5905的图8(将需要向下滚动到第18页):
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |li | VN |Mode | Stratum | Poll | Precision | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
我在图8中看到的一件事是模式,版本和跳跃应该组成第一个字节。
将模式,版本和跳转类型从unsigned int更改为unsigned char以便您的按位变量只跨越1个字节而不是4个。这将使您的NTPMessage大小预期为48个字节。
喜欢:
struct NTPMessage { unsigned char mode :3; unsigned char version :2; unsigned char leap :2; …
总结
以上是内存溢出为你收集整理的Windows中的基本NTP客户端在Visual C ++中全部内容,希望文章能够帮你解决Windows中的基本NTP客户端在Visual C ++中所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
请登录后查看评论内容