QT ntp和摆脱差异

时间:2014-08-05 01:15:27

标签: c++ c multithreading qt ntp

我从其他用户那里获得了代码 link

我连接到:pool.ntp.org

但我不能及时发现任何差异。 (我需要与ntp服务器完美同步 - 然后我会很高兴)

我的代码:

time_t t = response.tx.to_time_t();
char *s = ctime(&t);

WSACleanup();

h_qtimeonStatusBar->setDateTime(QDateTime::fromTime_t(response.tx.to_time_t()));

但首先我有这段代码:

getNTPTime(); //function above
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(updateTime())); // update time = current time from 'getNTPTime()' + 1 s
timer->start(0);
timer->setInterval(1000);

我的差异是以毫秒为单位(最大1000),但它确实可见。 我的时钟比ntp服务器慢慢点亮(这是可靠的信息)

如何摆脱这种差异?

我试着用它:

//func run after program start
{
        getNTPTime();
        QTimer *timer = new QTimer(this);
        connect(timer, SIGNAL(timeout()), this, SLOT(updateTime()));
        timer->start(0);
        timer->setInterval(1000);
}


bool plemionabot1::getNTPTime(){
        using namespace std::chrono;
        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, 0, sizeof(srv_addr));
        msg.dns_lookup(host, &srv_addr); /* Helper function defined below. */

        msg.sendto(sock, &srv_addr);
        auto t0 = high_resolution_clock::now();
        response.recv(sock);
        time_t t = response.tx.to_time_t();
        char *s = ctime(&t);

        WSACleanup();
        //QDateTime * tmp = new QDateTime;
        //tmp->setMSecsSinceEpoch(response.tx.seconds); // time is too much
        //h_qtimeonStatusBar->setDateTime(tmp->currentDateTime());
        h_qtimeonStatusBar->setDateTime(QDateTime::fromTime_t(response.tx.to_time_t())); // tą opcją wychodzi za mało
        auto t1 = high_resolution_clock::now();
        h_qtimeonStatusBar->setTime(h_qtimeonStatusBar->time().addMSecs(duration_cast<milliseconds>(t1-t0).count())); // time not enough
        return true;
}

1 个答案:

答案 0 :(得分:2)

来自QTimer documentation

  

精度和定时器分辨率

     

定时器永远不会超过指定的超时值超时,并且不能保证它们以指定的确切值超时。在许多情况下,它们可能会延迟一段时间,这段时间取决于系统计时器的准确性。

您无法依靠QTimer为您保留准确的时间。

相反,您需要做的是计算自上次查询NTP服务器以来的已用时间。经过的时间取决于您的系统时钟,它可能也会漂移,但这不是同一个问题。记录查询NTP服务器后经过的时间,并将其添加到查询NTP服务器时的系统时钟时间,以更好地估计当前的NTP时间。

更好的方法是设置ntpd,以便系统时钟自动调整到NTP时间。那么您的应用程序不必担心这一点,您只需显示系统时间即可。