Я получил код от другого пользователя
ссылка на сайт
И я подключаюсь к: 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;
}
Точность и разрешение по таймеру
Таймеры никогда не истечут раньше, чем указанное значение тайм-аута, и им не гарантируется тайм-аут с точным указанным значением. Во многих ситуациях они могут задержаться на определенный промежуток времени, который зависит от точности системных таймеров.
Вы не можете полагаться на QTimer
держать точное время для вас.
Вместо этого вам нужно вычислить истекшее время с момента последнего запроса NTP-сервера. Истекшее время зависит от ваших системных часов, которые также могут дрейфовать, но это не та проблема. Возьмите истекшее время с момента запроса NTP-сервера и добавьте его к системным часам с момента запроса NTP-сервера, чтобы получить более точную оценку текущего времени NTP.
Лучше всего настроить ntpd так, чтобы системные часы автоматически настраивались на время NTP. Тогда вашему приложению не нужно беспокоиться об этом, и вы можете просто отобразить системное время.