通过NTP服务器获取网络时间C++

来源:互联网 发布:若风外设淘宝店地址 编辑:程序博客网 时间:2024/05/17 08:36

通过NTP服务器获取网络时间

#include <winsock2.h>
#include <ws2tcpip.h>
#include<ctime>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#pragma   comment   (lib,"Ws2_32.lib")

#define NTP_PORT                  123               /*NTP专用端口号字符串*/
#define NTP_SERVER_IP        "ntp1.aliyun.com"  
#define NTP_PORT_STR         "123"          
#define JAN_1970 0x83aa7e80 /* 1900年~1970年之间的时间秒数 */

/*
来自阿里云的 NTP 服务器:【7个】
ntp1.aliyun.com
ntp2.aliyun.com
ntp3.aliyun.com
ntp4.aliyun.com
ntp5.aliyun.com
ntp6.aliyun.com
ntp7.aliyun.com
*/

struct NTPPacket
{
    union
    {
        struct _ControlWord
        {
            unsigned int uLI : 2;       // 00 = no leap, clock ok   
            unsigned int uVersion : 3;  // version 3 or version 4
            unsigned int uMode : 3;     // 3 for client, 4 for server, etc.
            unsigned int uStratum : 8;  // 0 is unspecified, 1 for primary reference system,
            // 2 for next level, etc.
            int nPoll : 8;              // seconds as the nearest power of 2
            int nPrecision : 8;         // seconds to the nearest power of 2
        };

        int nControlWord;             // 4
    };

    int nRootDelay;                   // 4
    int nRootDispersion;              // 4
    int nReferenceIdentifier;         // 4

    __int64 n64ReferenceTimestamp;    // 8
    __int64 n64OriginateTimestamp;    // 8
    __int64 n64ReceiveTimestamp;      // 8

    int nTransmitTimestampSeconds;    // 4
    int nTransmitTimestampFractions;  // 4
};


//获取的时间为1970年1月1日到现在的秒数
int Get_time_t(time_t & ttime)
{
    ttime = 0;
    WSADATA wsaData;
    // Initialize Winsock
    int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) return 0;

    int sockfd, rc;
    addrinfo hints, *res = NULL;
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_DGRAM;
    hints.ai_protocol = IPPROTO_UDP;
    rc = getaddrinfo(NTP_SERVER_IP, NTP_PORT_STR, &hints, &res);

    if (rc != 0) return 0;

    sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
    if (sockfd < 0) return 0;

    fd_set pending_data;
    timeval block_time;

    int data_len = hints.ai_addrlen, count = 0, result;

    NTPPacket ntpSend = { 0 };
    ntpSend.nControlWord = 0x1B;
    NTPPacket ntpRecv;
    if ((result = sendto(sockfd, (const char*)&ntpSend, sizeof(NTPPacket), 0, hints.ai_addr, data_len)) < 0)
        return 0;

    FD_ZERO(&pending_data);
    FD_SET(sockfd, &pending_data);

    //timeout 10 sec
    block_time.tv_sec = 10;
    block_time.tv_usec = 0;

    if (select(sockfd + 1, &pending_data, NULL, NULL, &block_time) > 0)
    {
        //获取的时间为1900年1月1日到现在的秒数
        if ((count = recvfrom(sockfd, (char*)&ntpRecv, sizeof(NTPPacket), 0, hints.ai_addr, &data_len)) > 0)
            ttime = ntohl(ntpRecv.nTransmitTimestampSeconds) - JAN_1970;
    }

    closesocket(sockfd);

    WSACleanup();
    return 1;
}






原创粉丝点击