C++ QT ntp和消除差异
我从另一个用户那里得到了代码 我连接到:pool.ntp.org 但我不能在时间上有任何差异。(我需要与ntp服务器完美同步-然后我会很高兴) 我的代码:C++ QT ntp和消除差异,c++,c,multithreading,qt,ntp,C++,C,Multithreading,Qt,Ntp,我从另一个用户那里得到了代码 我连接到: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())); 但首先我有这个代码
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;
}
//程序启动后运行func
{
getNTPTime();
QTimer*定时器=新的QTimer(此);
连接(计时器、信号(timeout())、此、插槽(updateTime());
定时器->启动(0);
定时器->设置间隔(1000);
}
bool plemionabot1::getNTPTime(){
使用名称空间std::chrono;
WSADATA WSADATA;
DWORD ret=WSAStartup(MAKEWORD(2,0)和wsaData);
char*host=“pool.ntp.org”/*不要分发指向此处的内容,这是不礼貌的*/
//char*host=“time.nist.gov”/*这个可能还可以,但在调试过程中可能会对请求速率产生不满*/
NTPMessage msg;
/*重要提示:如果不设置版本/模式,服务器将忽略您*/
msg.clear();
msg.version=3;
msg.mode=3/*客户机*/;
NTP消息响应;
response.clear();
int sock=插座(PF INET、sock DGRAM、IPPROTO_UDP);
srv_addr中的sockaddr_;
memset(&srv_addr,0,sizeof(srv_addr));
msg.dns_lookup(host,&srv_addr);/*助手函数定义如下*/
消息发送到(sock和srv_addr);
自动t0=高分辨率时钟::现在();
回复:recv(sock);
time_t=response.tx.to_time_t();
char*s=ctime(&t);
WSACleanup();
//QDateTime*tmp=新的QDateTime;
//tmp->setmsecsinceepoch(response.tx.seconds);//时间太长
//h_qTimeStatusBar->setDateTime(tmp->currentDateTime());
h_qtimestatusbar->setDateTime(QDateTime::fromTime_t(response.tx.to_time_t());//tąopcjąwychodzi za mało
自动t1=高分辨率时钟::现在();
h_qtimestatusbar->setTime(h_qtimestatusbar->time().addMSecs(duration_cast(t1-t0.count());//时间不够
返回true;
}
来自:
精度和计时器分辨率
计时器永远不会在指定的超时值之前超时,并且不保证在指定的确切值时超时。在许多情况下,它们可能会超时一段时间,这取决于系统计时器的准确性
您不能依靠QTimer
来为您保持准确的时间
相反,您需要做的是计算自上次查询NTP服务器以来经过的时间。经过的时间是基于您的系统时钟,它也可能会漂移,但这不是同一个问题。获取查询NTP服务器后经过的时间,并将其添加到查询NTP服务器后的系统时钟时间中,以更好地估计当前NTP时间
更好的方法是设置ntpd,以便系统时钟自动调整为NTP时间。那么您的应用程序就不必担心这个问题,您可以简单地显示系统时间。我应该用什么来代替QTimer?(取而代之的是ntpd)从ntp我没有任何毫秒来同步我的时钟?(我想我得到的是秒和毫秒)以及如何将这些毫秒设置为
QDateTime::fromTime\t()
?您仍然可以使用QTimer向应用程序发送信号,以更新屏幕上的时钟。但是,您必须进行如上所述的计算,而不是简单地在时钟上加1秒。那么ntp服务器上的毫秒呢?大概您可以从消息的tx.fraction
成员处获得毫秒数(如您链接的问题所示)。但是,更好的解决方案仍然是安装一个真正的ntpd,而不是在应用程序中管理它。您能告诉我如何在QDateTime中设置毫秒时间吗?我在sendto之后设置时间点,在recv之后设置秒-并将其添加到我的时间中,但这仍然不够<代码>h_qtimestatusbar->setDateTime(QDateTime::fromTime_t(response.tx.to_time_t())我认为这是这个的错,你有其他想法吗?