使用Qt獲取NTP服務(wù)器時間的方法及示例

admin2年前 (2023-07-12)時頻百科792

  使用Qt獲取NTP服務(wù)器時間是一個實(shí)用的功能,這樣可以使得程序在使用時更加準(zhǔn)確,下面將會對這個功能進(jìn)行詳細(xì)的闡述。

  

1、QNetworkDatagram的使用

Qt提供了一個類QNetworkDatagram,用于在網(wǎng)絡(luò)上發(fā)送和接收數(shù)據(jù)報。我們可以通過它發(fā)送一個NTP協(xié)議的請求。這個請求是一個48字節(jié)的數(shù)據(jù)報,它的前48字節(jié)是0,第一個字節(jié)是17代表NTPv4,后面的字節(jié)里是一些控制信息。發(fā)送該數(shù)據(jù)報后,等待服務(wù)器返回48字節(jié)的應(yīng)答即可得到服務(wù)器的時間信息。

使用Qt獲取NTP服務(wù)器時間的方法及示例

  使用QNetworkDatagram類來實(shí)現(xiàn)發(fā)送和接收數(shù)據(jù)包的代碼如下:

  ```

  QByteArray requestData(48, 0);

  requestData[0] = 0x1b; // 設(shè)置NTP協(xié)議版本

  QNetworkDatagram datagram(requestData, QHostAddress("pool.ntp.org"), 123);

  QUdpSocket udpSocket;

  udpSocket.writeDatagram(datagram);

  if (udpSocket.waitForReadyRead(3000)) {

   QByteArray data;

   data.resize(udpSocket.pendingDatagramSize());

   udpSocket.readDatagram(data.data(), data.size());

   // 對獲取的數(shù)據(jù)字節(jié)進(jìn)行時間計算處理

  } else {

   qDebug() << "Request timeout";

  ```

  在上述代碼中,我們通過QByteArray對象建立了一個長度為48、且所有位都是0的數(shù)組,然后通過這個數(shù)組以及QHostAddress類創(chuàng)建了一個QNetworkDatagram對象,并將其發(fā)送到指定的主機(jī)地址和端口。如果在指定時間內(nèi)沒有收到來自服務(wù)器的應(yīng)答,則認(rèn)為該次請求超時。

  

2、將時間戳轉(zhuǎn)化為人類可讀的時間

獲取NTP服務(wù)器時間后,我們需要將時間戳轉(zhuǎn)化為人類可讀的時間??梢酝ㄟ^函數(shù)time_t ntohl(time_t netlong)將網(wǎng)絡(luò)字節(jié)序的32位無符號整數(shù)轉(zhuǎn)換為主機(jī)字節(jié)序的32位無符號整數(shù)。

  下面是將網(wǎng)絡(luò)字節(jié)序的64位時間戳轉(zhuǎn)換為人可讀的時間的代碼:

  ```

  QByteArray data; // 從服務(wù)器獲取的數(shù)據(jù)

  unsigned long long NTP_TIMESTAMP_DELTA = 2208988800ull; // 參考時間:1900年1月1日

  time_t high = ntohl(*((uint32_t*)&data[40])) - NTP_TIMESTAMP_DELTA;

  time_t low = ntohl(*((uint32_t*)&data[44]));

  time_t ntp_time = (high << 32) low;

  QDateTime utc(QDate(1900, 1, 1), QTime(0, 0, 0), Qt::UTC);

  QDateTime current(utc.addSecs(ntp_time));

  qDebug() << "Current time is" << current;

  ```

  在上述代碼中,我們首先將從服務(wù)器獲取的64位時間戳分別存儲在high和low變量中,然后將它們拼接成一個新的64位時間戳ntp_time。接著,我們根據(jù)參考時間以及加上ntp_time計算出QDateTime對象current表示當(dāng)前時間。

  

3、使用定時器獲取服務(wù)器時間

我們可以使用Qt中的QTimer定時器類,并在定時器的槽函數(shù)中實(shí)現(xiàn)NTP協(xié)議的請求和計算NTP服務(wù)器時間的過程。

  下面的代碼演示了如何使用QTimer類來獲取NTP服務(wù)器時間:

  ```

  void MainWindow::startTimer()

   QTimer *timer = new QTimer(this);

   connect(timer, &QTimer::timeout, this, &MainWindow::onTimer);

   timer->start(1000); // 每隔1秒執(zhí)行一次onTimer()

  void MainWindow::onTimer()

   QByteArray requestData(48, 0);

   requestData[0] = 0x1b;

   QNetworkDatagram datagram(requestData, QHostAddress("pool.ntp.org"), 123);

   QUdpSocket udpSocket;

   udpSocket.writeDatagram(datagram);

   if (udpSocket.waitForReadyRead(3000)) {

   QByteArray data;

   data.resize(udpSocket.pendingDatagramSize());

   udpSocket.readDatagram(data.data(), data.size());

   // 進(jìn)行時間戳處理

   unsigned long long NTP_TIMESTAMP_DELTA = 2208988800ull;

   time_t high = ntohl(*((uint32_t*)&data[40])) - NTP_TIMESTAMP_DELTA;

   time_t low = ntohl(*((uint32_t*)&data[44]));

   time_t ntp_time = (high << 32) low;

   QDateTime utc(QDate(1900, 1, 1), QTime(0, 0, 0), Qt::UTC);

   QDateTime current(utc.addSecs(ntp_time));

   qDebug() << "Current time is" << current;

   } else {

   qDebug() << "Request timeout";

   }

  ```

  在上述代碼中,我們首先在startTimer()函數(shù)中創(chuàng)建了一個QTimer對象,并將它與onTimer()槽函數(shù)連接并定時啟動。在onTimer函數(shù)中,我們使用了前面提到的QNetworkDatagram類發(fā)送了一個NTP協(xié)議的請求,并通過時間戳計算得到了當(dāng)前的時間,并打印到控制臺上。

  

4、使用并發(fā)框架多線程并發(fā)地獲取服務(wù)器時間

對于高并發(fā)和網(wǎng)絡(luò)阻塞等問題,我們可以使用Qt提供的QThreadPool類實(shí)現(xiàn)多線程并發(fā)獲取NTP服務(wù)器時間。

  下面的代碼展示了如何使用QThreadPool和QRunnable類來實(shí)現(xiàn)多線程并發(fā)獲取NTP服務(wù)器時間:

  ```

  class TimeRunnable : public QRunnable

  public:

   TimeRunnable(const QString &server) : _server(server) {}

   void run() override {

   QByteArray requestData(48, 0);

   requestData[0] = 0x1b;

   QNetworkDatagram datagram(requestData, QHostAddress(_server), 123);

   QUdpSocket udpSocket;

   udpSocket.writeDatagram(datagram);

   if (udpSocket.waitForReadyRead(3000)) {

   QByteArray data;

   data.resize(udpSocket.pendingDatagramSize());

   udpSocket.readDatagram(data.data(), data.size());

   // 進(jìn)行時間戳處理

   unsigned long long NTP_TIMESTAMP_DELTA = 2208988800ull;

   time_t high = ntohl(*((uint32_t*)&data[40])) - NTP_TIMESTAMP_DELTA;

   time_t low = ntohl(*((uint32_t*)&data[44]));

   time_t ntp_time = (high << 32) low;

   QDateTime utc(QDate(1900, 1, 1), QTime(0, 0, 0), Qt::UTC);

   QDateTime current(utc.addSecs(ntp_time));

   emit currentTime(current);

   }

   }

  signals:

   void currentTime(const QDateTime &);

  };

  class MainWindow : public QMainWindow

   Q_OBJECT

  public:

   MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) {

   _pool.setMaxThreadCount(10); // 設(shè)置線程池最大線程數(shù)

   }

   ~MainWindow() {}

  public slots:

   void onTime(const QDateTime ¤t) {

   qDebug() << "Current time is" << current;

   }

   void onStart() {

   for (const auto &server : _servers) {

   TimeRunnable *runnable = new TimeRunnable(server);

   connect(runnable, &TimeRunnable::currentTime, this, &MainWindow::onTime);

   _pool.start(runnable);

   }

   }

  private:

   QVector _servers{"pool.ntp.org", "cn.ntp.org.cn", "time.windows.com"};

   QThreadPool _pool;

  };

  ```

  在上述代碼中,我們創(chuàng)建了一個名為TimeRunnable的類,其中包含發(fā)送和接收NTP請求的代碼,并通過signals和slots機(jī)制與MainWindow類連接。在MainWindow類中,我們首先創(chuàng)建了一個QThreadPool對象,并在onStart()槽函數(shù)中,用服務(wù)器名字自動運(yùn)行TimeRunnable的實(shí)例,并將currentTime信號與onTime槽函數(shù)連接,以便在收到服務(wù)器時間時輸出到控制臺上。

  經(jīng)過上述改進(jìn),我們可以同時對多個NTP服務(wù)器進(jìn)行請求,增加了代碼的魯棒性并加快了時間獲取速度。

  總結(jié):

  使用Qt獲取NTP服務(wù)器時間是一個強(qiáng)大的功能,可以在許多實(shí)際應(yīng)用中發(fā)揮重要作用。在本文中我們提到了4個方法:使用QNetworkDatagram發(fā)送和接收請求、將時間戳轉(zhuǎn)化為人類可讀的時間、使用定時器獲取時間和使用并發(fā)框架獲取NTP服務(wù)器時間等。這些方法體現(xiàn)了Qt在網(wǎng)絡(luò)操作方面的強(qiáng)大實(shí)力,同時也為我們在實(shí)際應(yīng)用中更好地使用Qt提供了不少思路。

  感謝您的閱讀,希望這篇文章能夠?qū)δ兴鶐椭?

標(biāo)簽: 時頻百科

相關(guān)文章

Java服務(wù)器時間同步方案

Java服務(wù)器時間同步方案

  本文將圍繞Java服務(wù)器時間同步方案展開闡述,主要包括時間同步的概念、同步方式及其優(yōu)缺點(diǎn)、NTP協(xié)議的應(yīng)用、以及Java服務(wù)器時間同步方案的實(shí)現(xiàn)方式等方面進(jìn)行詳細(xì)闡述。    1、時間同步的概念 時間同步是指在一個網(wǎng)絡(luò)環(huán)境中,通過各種方式來保證所有主機(jī)的時間保持一致。時間同步是網(wǎng)絡(luò)通信中重要的環(huán)節(jié),因?yàn)楹芏鄳?yīng)用程序的正確運(yùn)行需要時間的參考。同時,時間同步對于維護(hù)系統(tǒng)安全也有著相當(dāng)大的重要性。...

《激戰(zhàn)2》「時空卡縛」新活動震撼來襲!

《激戰(zhàn)2》「時空卡縛」新活動震撼來襲!

  激戰(zhàn)2作為一款備受矚目的網(wǎng)絡(luò)游戲,以其獨(dú)特的世界觀、精美的畫面、豐富的玩法,吸引了大量的玩家。而此次「時空卡縛」新活動的震撼來襲,則讓玩家們更加激動和期待。在本文中,我們將從四個方面對這一活動進(jìn)行詳細(xì)闡述,為大家揭示其中的精彩細(xì)節(jié)。    1、全新的劇情設(shè)定 這一次,在新活動中,玩家們將會遇到一個神秘的人物——候選人。候選人的出現(xiàn)將給游戲帶來全新的劇情設(shè)定。除此之外,冰女王及其親信騎士長也將在本次活動中引領(lǐng)玩家探索全新的冰...

Moba游戲時間如何影響服務(wù)器運(yùn)算

Moba游戲時間如何影響服務(wù)器運(yùn)算

  本文將探討"Moba游戲時間如何影響服務(wù)器運(yùn)算"這一話題。在電子競技行業(yè)中,Moba系列游戲一直占據(jù)著重要的地位。然而,隨著游戲時間的增長,Moba游戲的服務(wù)器運(yùn)算將會受到怎樣的影響呢?本文將從四個方面闡述這一問題。    1、游戲數(shù)據(jù)的收集和傳輸 第一個方面是游戲數(shù)據(jù)的收集和傳輸。在Moba游戲中,玩家的每一個操作都會被記錄在服務(wù)器上。隨著游戲時間的增長,玩家操作產(chǎn)生的數(shù)據(jù)也隨之增多。大量數(shù)據(jù)的傳輸需...

LOL手游服務(wù)器公測時間:玩家等待已久,開服時間終于確定!

LOL手游服務(wù)器公測時間:玩家等待已久,開服時間終于確定!

  LOL手游服務(wù)器公測時間:玩家等待已久,開服時間終于確定!本文將從四個方面對此次公測進(jìn)行詳細(xì)的闡述,包括公測時間確定、公測玩法介紹、游戲特色以及期待的內(nèi)容。讓我們一同期待這一次的開啟!    1、公測時間確定 在玩家的期盼中,LOL手游公測時間終于確定。據(jù)官方消息,LOL手游將于2020年6月1日正式開啟公測。這個時間點(diǎn)也是玩家們最為期待的時間之一,因?yàn)檫@是很多人準(zhǔn)備加入游戲的最佳機(jī)會。...

《笑傲江湖OL》服務(wù)器精彩活動時間表!

《笑傲江湖OL》服務(wù)器精彩活動時間表!

  本文將就《笑傲江湖OL》服務(wù)器精彩活動時間表,對其進(jìn)行詳細(xì)介紹與分析,包括四個方面,分別是節(jié)日活動、比賽賽事、限時活動以及永久活動。這些活動涵蓋了游戲中的大部分內(nèi)容,幾乎每一個玩家都可以找到自己喜歡的活動。下面我們就來一一介紹。    1、節(jié)日活動 節(jié)日活動是《笑傲江湖OL》服務(wù)器精彩活動時間表的重要部分,無論是游戲內(nèi)的節(jié)日活動還是現(xiàn)實(shí)生活中的節(jié)日活動,都會在游戲中得到精心設(shè)計和策劃,讓玩家有一種身臨其境的感覺。春節(jié)活動、...

Linux系統(tǒng)手動將時鐘與服務(wù)器時間同步操作方法

Linux系統(tǒng)手動將時鐘與服務(wù)器時間同步操作方法

  現(xiàn)在,越來越多的服務(wù)器采用Linux系統(tǒng),因此,我們需要知道如何手動將時鐘與服務(wù)器時間同步,以確保系統(tǒng)時間的準(zhǔn)確性。本文將詳細(xì)介紹Linux系統(tǒng)手動將時鐘與服務(wù)器時間同步的操作方法。    1、時鐘同步原理 在介紹如何手動將時鐘與服務(wù)器時間同步之前,首先需要了解時鐘同步的原理。Linux系統(tǒng)中有一個硬件時鐘和一個系統(tǒng)時鐘,硬件時鐘記錄系統(tǒng)的時間,當(dāng)系統(tǒng)啟動時會將硬件時鐘的時間拷貝到系統(tǒng)時鐘中,之后系統(tǒng)時鐘將獨(dú)立運(yùn)行。服務(wù)器...

JavaScript實(shí)現(xiàn)獲取服務(wù)器時間并解決亂碼問題

JavaScript實(shí)現(xiàn)獲取服務(wù)器時間并解決亂碼問題

  JavaScript是一種腳本語言,它被廣泛應(yīng)用于Web開發(fā)中。在Web開發(fā)中,獲取服務(wù)器時間并解決亂碼問題是一個很常見的需求。本文以JavaScript實(shí)現(xiàn)獲取服務(wù)器時間并解決亂碼問題為主題,從4個方面對其進(jìn)行詳細(xì)闡述。    1、獲取服務(wù)器時間 JavaScript可以通過HTTP請求獲取服務(wù)器時間。這里使用了XMLHttpRequest對象來向服務(wù)器發(fā)送請求,并且在接收到服務(wù)器響應(yīng)后,將服務(wù)器時間以Date對象的形式...

Linux服務(wù)器長時間連接問題探究

Linux服務(wù)器長時間連接問題探究

  Linux服務(wù)器長時間連接問題是Linux服務(wù)器面臨的最常見問題之一,長時間連接不僅會影響網(wǎng)絡(luò)性能,還可能導(dǎo)致服務(wù)器崩潰,影響系統(tǒng)安全性。本文從四個方面探究Linux服務(wù)器長時間連接問題,包括發(fā)現(xiàn)問題、問題分析、解決方案以及問題預(yù)防。通過深入研究,我們可以找到針對Linux服務(wù)器長時間連接問題的最佳解決方案。    1、發(fā)現(xiàn)問題 Linux服務(wù)器長時間連接問題很難被察覺,因此及時發(fā)現(xiàn)問題尤為重要。有以下幾種方式可以幫助我們...

CentOS同步時間服務(wù)器操作指南

CentOS同步時間服務(wù)器操作指南

  本文將為大家詳細(xì)介紹CentOS同步時間服務(wù)器操作指南。CentOS操作系統(tǒng)同步時間服務(wù)器是一項非常重要的操作,它可以確保服務(wù)器的時間與各個客戶端的時間是準(zhǔn)確無誤的。本文將從以下四個方面闡述CentOS操作系統(tǒng)同步時間服務(wù)器的方法,方便讀者快速掌握這一技巧。    1、配置NTP服務(wù)器同步時間 要在CentOS操作系統(tǒng)中同步時間服務(wù)器,首先需要配置NTP服務(wù)器。NTP是一種網(wǎng)絡(luò)時間協(xié)議,它允許計算機(jī)通過互聯(lián)網(wǎng)同步時間。在C...

CentOS服務(wù)器時間修改方法及步驟詳解

CentOS服務(wù)器時間修改方法及步驟詳解

  CentOS服務(wù)器時間修改方法及步驟是每臺服務(wù)器都需要掌握的重要知識。CentOS是一款極為穩(wěn)定的操作系統(tǒng),但是在DST和時區(qū)等方面也需要進(jìn)行一定的設(shè)置。本文將從設(shè)置時區(qū)、同步網(wǎng)絡(luò)時間、手動修改服務(wù)器時間和防止時間偏移等四個方面詳細(xì)講解CentOS服務(wù)器時間修改的技巧和方法。    1、設(shè)置時區(qū) 時區(qū)是控制時間變化的核心設(shè)置,每個地區(qū)的時區(qū)是不一樣的。因此,在新建服務(wù)器的時候,時區(qū)的設(shè)置就尤為重要。CentOS中設(shè)置時區(qū)的...

H3C設(shè)置時間服務(wù)器為中心詳解

H3C設(shè)置時間服務(wù)器為中心詳解

  在網(wǎng)絡(luò)中,時間同步是一項至關(guān)重要的工作。準(zhǔn)確的時間同步可以保證系統(tǒng)正常工作,提高網(wǎng)絡(luò)服務(wù)的可靠性和穩(wěn)定性。而H3C作為一家網(wǎng)絡(luò)設(shè)備解決方案供應(yīng)商,它的時間服務(wù)器設(shè)置為網(wǎng)絡(luò)時間同步提供了完美解決方案。本文將圍繞H3C設(shè)置時間服務(wù)器為中心進(jìn)行詳細(xì)闡述,主要涵蓋四個方面:H3C時間服務(wù)器的概述、H3C時間服務(wù)器網(wǎng)絡(luò)時間協(xié)議的支持、H3C時間服務(wù)器的設(shè)置、以及H3C時間服務(wù)器的管理。    一、H3C時間服務(wù)器的概述 H3C時間服...

【如何以電腦服務(wù)器時間為中心進(jìn)行時間調(diào)整】

【如何以電腦服務(wù)器時間為中心進(jìn)行時間調(diào)整】

  本文主要探討如何以電腦服務(wù)器時間為中心進(jìn)行時間調(diào)整,以確保各類應(yīng)用程序的準(zhǔn)確性和時效性。時間同步是服務(wù)器管理中必不可少的一環(huán),它不僅關(guān)系到各種系統(tǒng)任務(wù)的正常執(zhí)行,也直接影響到網(wǎng)絡(luò)的準(zhǔn)確性和可靠性。因此,本文將從以下四個方面詳細(xì)闡述如何以電腦服務(wù)器時間為中心進(jìn)行時間調(diào)整。    1、配置網(wǎng)絡(luò)時間協(xié)議(NTP) 網(wǎng)絡(luò)時間協(xié)議(NTP)是一種用于同步計算機(jī)系統(tǒng)時鐘的協(xié)議,其作用是為多個設(shè)備提供準(zhǔn)確的時間源。因此,配置NTP可以使...

「如何設(shè)置NTP服務(wù)器地址并同步網(wǎng)絡(luò)時間?」

「如何設(shè)置NTP服務(wù)器地址并同步網(wǎng)絡(luò)時間?」

  在網(wǎng)絡(luò)應(yīng)用中,維護(hù)時間同步對于保證系統(tǒng)的一致性和可靠性至關(guān)重要。為了實(shí)現(xiàn)時間同步,使用網(wǎng)絡(luò)時間協(xié)議(NTP)是一種有效的方法。本文將介紹如何設(shè)置NTP服務(wù)器地址并同步網(wǎng)絡(luò)時間。    1、查找可用的NTP服務(wù)器 在設(shè)置NTP服務(wù)器之前,需要先查找可用的NTP服務(wù)器地址??梢灾苯釉谒阉饕嬷休斎搿翱捎玫腘TP服務(wù)器”進(jìn)行搜索,也可以訪問一些公共NTP服務(wù)器提供的網(wǎng)站。一些著名的公共NTP服務(wù)器包括:time.windows....

Linux服務(wù)器時間同步指南:設(shè)置正確時間為中心

Linux服務(wù)器時間同步指南:設(shè)置正確時間為中心

  Linux服務(wù)器時間同步對于系統(tǒng)的正常運(yùn)行至關(guān)重要,同時也對系統(tǒng)安全、日志記錄等方面產(chǎn)生影響。本文旨在為大家提供一個設(shè)置正確時間為中心的指南,從時間同步原理、時間同步方式、時間同步配置和時間同步故障排除方面對Linux服務(wù)器時間同步進(jìn)行詳細(xì)闡述。    1、時間同步原理 在計算機(jī)系統(tǒng)中,時間的標(biāo)準(zhǔn)是UTC(世界協(xié)調(diào)時)。為了方便使用和維護(hù),操作系統(tǒng)會將UTC時間轉(zhuǎn)換成本地時間。服務(wù)器之間的時間差異可能會影響校時、安全日志等...

Linux服務(wù)器時間配置詳解

Linux服務(wù)器時間配置詳解

     本文將對Linux服務(wù)器時間配置進(jìn)行詳細(xì)的解析。Linux服務(wù)器時間配置是系統(tǒng)中重要的一部分,它直接影響到整個系統(tǒng)的時間,因此要做好時間配置,是保證系統(tǒng)穩(wěn)定運(yùn)行的關(guān)鍵。    1、時間同步 時間同步是指將不同設(shè)備的時間同步。因?yàn)槊總€設(shè)備的時間是不...