使用NTP协议获取网络时间代码
2014-04-21 20:59
489 查看
协议包:
主要字段的解释如下:
l LI(Leap Indicator):长度为2比特,值为“11”时表示告警状态,时钟未被同步。为其他值时NTP本身不做处理。
l VN(Version Number):长度为3比特,表示NTP的版本号,目前的最新版本为3。
l Mode:长度为3比特,表示NTP的工作模式。不同的值所表示的含义分别是:0未定义、1表示主动对等体模式、2表示被动对等体模式、3表示客户模式、4表示服务器模式、5表示广播模式或组播模式、6表示此报文为NTP控制报文、7预留给内部使用。
l Stratum:系统时钟的层数,取值范围为1~16,它定义了时钟的准确度。层数为1的时钟准确度最高,准确度从1到16依次递减,层数为16的时钟处于未同步状态,不能作为参考时钟。
l Poll:轮询时间,即两个连续NTP报文之间的时间间隔。
l Precision:系统时钟的精度。
l Root Delay:本地到主参考时钟源的往返时间。
l Root Dispersion:系统时钟相对于主参考时钟的最大误差。
l Reference Identifier:参考时钟源的标识。
l Reference Timestamp:系统时钟最后一次被设定或更新的时间。
l Originate Timestamp:NTP请求报文离开发送端时发送端的本地时间。
l Receive Timestamp:NTP请求报文到达接收端时接收端的本地时间。
l Transmit Timestamp:应答报文离开应答者时应答者的本地时间。
l Authenticator:验证信息。
字段解释来自 http://blog.163.com/yzc_5001/blog/static/2061963420121283050787/
主要字段的解释如下:
l LI(Leap Indicator):长度为2比特,值为“11”时表示告警状态,时钟未被同步。为其他值时NTP本身不做处理。
l VN(Version Number):长度为3比特,表示NTP的版本号,目前的最新版本为3。
l Mode:长度为3比特,表示NTP的工作模式。不同的值所表示的含义分别是:0未定义、1表示主动对等体模式、2表示被动对等体模式、3表示客户模式、4表示服务器模式、5表示广播模式或组播模式、6表示此报文为NTP控制报文、7预留给内部使用。
l Stratum:系统时钟的层数,取值范围为1~16,它定义了时钟的准确度。层数为1的时钟准确度最高,准确度从1到16依次递减,层数为16的时钟处于未同步状态,不能作为参考时钟。
l Poll:轮询时间,即两个连续NTP报文之间的时间间隔。
l Precision:系统时钟的精度。
l Root Delay:本地到主参考时钟源的往返时间。
l Root Dispersion:系统时钟相对于主参考时钟的最大误差。
l Reference Identifier:参考时钟源的标识。
l Reference Timestamp:系统时钟最后一次被设定或更新的时间。
l Originate Timestamp:NTP请求报文离开发送端时发送端的本地时间。
l Receive Timestamp:NTP请求报文到达接收端时接收端的本地时间。
l Transmit Timestamp:应答报文离开应答者时应答者的本地时间。
l Authenticator:验证信息。
class NetworkUInt64 { public: operator UINT64() { return htonll(nData); } const NetworkUInt64& operator = (UINT64 nValue) { nData = htonll(nValue); return *this; } protected: UINT64 nData; }; const static ULONGLONG n1970_1900_Seconds = 2208988800; __declspec(align(1)) struct NTPData { unsigned int Mode : 3; unsigned int VersionNumber : 3; unsigned int LeapIndicator : 2; unsigned int Stratum : 8; unsigned int Poll : 8; unsigned int Precision : 8; unsigned int RootDelay : 32; unsigned int RootDispersion : 32; unsigned int ReferenceIdentifier : 32; NetworkUInt64 ReferenceTimestamp; NetworkUInt64 OriginateTimestamp; NetworkUInt64 ReceiveTimestamp; NetworkUInt64 TransmitTimestamp; }; int _tmain(int argc, _TCHAR* argv[]) { setlocale(LC_ALL, ".ACP"); WSADATA wsaData; SOCKET SendSocket; sockaddr_in RecvAddr; int Port = 123; //--------------------------------------------- // Initialize Winsock WSAStartup(MAKEWORD(2, 2), &wsaData); //--------------------------------------------- // Create a socket for sending data SendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //--------------------------------------------- // Set up the RecvAddr structure with the IP address of // the receiver (in this example case "123.456.789.1") // and the specified port number. RecvAddr.sin_family = AF_INET; RecvAddr.sin_port = htons(Port); HOSTENT* pHostent = gethostbyname("time.nist.gov"); if (pHostent != NULL) { RecvAddr.sin_addr.s_addr = *(u_long *)pHostent->h_addr_list[0];; } //--------------------------------------------- // Send a datagram to the receiver printf("Sending a datagram to the receiver...\n"); // Set version number to 3 and Mode to 3 (client) NTPData data = { 0 }; data.VersionNumber = 3; data.Mode = 3; int tv_out = 10000; setsockopt(SendSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv_out, sizeof(tv_out)); __time64_t startTime = _time64(NULL); sendto(SendSocket, (char*)&data, sizeof(data), 0, (SOCKADDR *)&RecvAddr, sizeof(RecvAddr)); sockaddr fromAddr = { 0 }; int nRead = sizeof(fromAddr); if (SOCKET_ERROR != recvfrom(SendSocket, (char*)&data, sizeof(data), 0, &fromAddr, &nRead)) { __time64_t curTime = _time64(NULL); __time64_t serverReceiveTime = (UINT64(data.ReceiveTimestamp) >> 32) - n1970_1900_Seconds; __time64_t serverTransmitTime = (UINT64(data.TransmitTimestamp) >> 32) - n1970_1900_Seconds; } else { cout << "WSAGetLastError:" << WSAGetLastError() << endl; } //--------------------------------------------- // When the application is finished sending, close the socket. printf("Finished sending. Closing socket.\n"); closesocket(SendSocket); //--------------------------------------------- // Clean up and quit. printf("Exiting.\n"); WSACleanup(); system("pause"); return 0; }
字段解释来自 http://blog.163.com/yzc_5001/blog/static/2061963420121283050787/
相关文章推荐
- NTP协议应用(获取网络时间)
- linux C++通过ntp协议获取网络时间
- linux C++通过ntp协议获取网络时间
- ntpdate命令_Linux ntpdate 命令用法详解:使用网络计时协议(NTP)设置日期和时间
- 网络时间协议(NTP)--网络大典
- ntp协议,android获取ntp时间
- 在vb中使用Iphlpapi.dll获取网络信息 第二章 第七节 获取本机网间控制报文协议(ICMP)信息
- android ntp和GPS获取网络时间问题
- 应对某些外包客户的无理,限制使用时间,获取网络时间
- RHCE 系列(十):在 RHEL/CentOS 7 中设置 NTP(网络时间协议)服务器
- 在vb中使用Iphlpapi.dll获取网络信息 第四章 第一节 错误代码
- 在Java下使用NTP获取时间
- 获取CPU时间戳代码 使用CPU时间戳进行高精度计时
- 使用Perl代码获取访问网页的载入时间
- Android手机虚拟CD-ROM流程 && 使用网络同步时间(NITZ和NTP)&& Android VOLD
- 【RL-TCPnet网络教程】第29章 NTP网络时间协议基础知识
- Linux的归档及压缩,Linux的cron时间计划任务, NTP网络时间协议 , 查看网络连接
- 同步网络时间的 NTP 协议被发现存在8个漏洞
- Android 网络:使用URLConnection提交请求,获取html代码加载WebView