QT ntp 并消除差异
Posted
技术标签:
【中文标题】QT ntp 并消除差异【英文标题】:QT ntp and getting rid of the differences 【发布时间】:2014-08-05 01:15:27 【问题描述】:我从另一个用户那里得到了代码 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;
【问题讨论】:
我在 sendto 之后创建时间点,在 recv 之后创建第二个时间点 - 并将其添加到我的时间,但仍然不够。h_qtimeonStatusBar->setDateTime(QDateTime::fromTime_t(response.tx.to_time_t()));
我认为这是错误的,你有其他想法吗?
【参考方案1】:
来自QTimer documentation:
精度和计时器分辨率
计时器永远不会早于指定的超时值超时,并且不能保证在指定的确切值时超时。在许多情况下,它们可能会延迟一段时间,具体取决于系统计时器的准确性。
您不能依赖QTimer
来为您保持准确的时间。
相反,您需要做的是计算自您上次查询 NTP 服务器以来的经过时间。经过的时间取决于您的系统时钟,它也可能会漂移,但这不是同一个问题。获取自查询 NTP 服务器以来经过的时间,并将其添加到查询 NTP 服务器时的系统时钟时间,以更好地估计当前 NTP 时间。
更好的方法是设置 ntpd,以便您的系统时钟自动调整为 NTP 时间。那么你的应用程序就不用担心这个了,你可以简单的显示系统时间。
【讨论】:
我应该用什么代替 QTimer ? (而不是ntpd)从ntp我没有得到任何毫秒来与我的时钟同步? (我以为我得到秒和毫秒)以及如何将这些毫秒放入QDateTime::fromTime_t()
?
您仍然可以使用 QTimer 来通知您的应用程序以更新屏幕上的时钟。但是,您必须像我上面描述的那样进行计算,而不是简单地将 1 加到时钟上。
那么来自 ntp 服务器的毫秒数呢?
大概您可以从消息的tx.fraction
成员那里获得毫秒数(如您链接到的问题所示)。但是,更好的解决方案仍然是安装真正的 ntpd,而不是在您的应用程序中管理它。
你能告诉我如何在 QDateTime 中以毫秒为单位设置时间吗?以上是关于QT ntp 并消除差异的主要内容,如果未能解决你的问题,请参考以下文章