RM新时代官网网址|首入球时间

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

admin2年前 (2023-07-12)時(shí)頻百科1183

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

  

1、QNetworkDatagram的使用

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

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

  使用QNetworkDatagram類(lèi)來(lái)實(shí)現發(fā)送和接收數據包的代碼如下:

  ```

  QByteArray requestData(48, 0);

  requestData[0] = 0x1b; // 設置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());

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

  } else {

   qDebug() << "Request timeout";

  ```

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

  

2、將時(shí)間戳轉化為人類(lèi)可讀的時(shí)間

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

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

  ```

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

  unsigned long long NTP_TIMESTAMP_DELTA = 2208988800ull; // 參考時(shí)間: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位時(shí)間戳分別存儲在high和low變量中,然后將它們拼接成一個(gè)新的64位時(shí)間戳ntp_time。接著(zhù),我們根據參考時(shí)間以及加上ntp_time計算出QDateTime對象current表示當前時(shí)間。

  

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

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

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

  ```

  void MainWindow::startTimer()

   QTimer *timer = new QTimer(this);

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

   timer->start(1000); // 每隔1秒執行一次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)行時(shí)間戳處理

   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()函數中創(chuàng )建了一個(gè)QTimer對象,并將它與onTimer()槽函數連接并定時(shí)啟動(dòng)。在onTimer函數中,我們使用了前面提到的QNetworkDatagram類(lèi)發(fā)送了一個(gè)NTP協(xié)議的請求,并通過(guò)時(shí)間戳計算得到了當前的時(shí)間,并打印到控制臺上。

  

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

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

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

  ```

  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)行時(shí)間戳處理

   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); // 設置線(xiàn)程池最大線(xiàn)程數

   }

   ~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 )建了一個(gè)名為T(mén)imeRunnable的類(lèi),其中包含發(fā)送和接收NTP請求的代碼,并通過(guò)signals和slots機制與MainWindow類(lèi)連接。在MainWindow類(lèi)中,我們首先創(chuàng )建了一個(gè)QThreadPool對象,并在onStart()槽函數中,用服務(wù)器名字自動(dòng)運行TimeRunnable的實(shí)例,并將currentTime信號與onTime槽函數連接,以便在收到服務(wù)器時(shí)間時(shí)輸出到控制臺上。

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

  總結:

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

  感謝您的閱讀,希望這篇文章能夠對您有所幫助!

相關(guān)文章

Intent時(shí)間服務(wù)器:強大穩定,全球多地域部署,提供高效精準服務(wù)

Intent時(shí)間服務(wù)器:強大穩定,全球多地域部署,提供高效精準服務(wù)

  Intent時(shí)間服務(wù)器:強大穩定,全球多地域部署,提供高效精準服務(wù)   在如今數字化時(shí)代,時(shí)間服務(wù)已成為人們生活中不可或缺的一部分,而Intent時(shí)間服務(wù)器無(wú)疑是這個(gè)領(lǐng)域中的領(lǐng)導者之一。該服務(wù)器旨在為全球用戶(hù)提供高品質(zhì)的時(shí)間服務(wù),通過(guò)強大穩定的技術(shù)支持和全球多地域部署,為用戶(hù)提供高效精準的時(shí)間服務(wù)。本文將從以下四個(gè)方面對Intent時(shí)間服務(wù)器的特點(diǎn)和優(yōu)勢做詳細闡述。   一、全球多地域部署   為了更好地為全球用戶(hù)提供時(shí)間服務(wù)...

ABAP代碼實(shí)現獲取服務(wù)器時(shí)間并格式化展示

ABAP代碼實(shí)現獲取服務(wù)器時(shí)間并格式化展示

  在現代企業(yè)信息化環(huán)境下,獲取服務(wù)器的時(shí)間并格式化展示是一個(gè)非?;A的需求。本文將通過(guò)ABAP代碼實(shí)現獲取服務(wù)器時(shí)間并格式化展示為中心,對該需求進(jìn)行詳細闡述。具體來(lái)說(shuō),本文將主要從以下四個(gè)方面入手:1、獲取服務(wù)器時(shí)間;2、時(shí)間格式化;3、時(shí)間的展示;4、實(shí)現代碼。通過(guò)對這四個(gè)方面的詳細闡述,讀者將能夠全面掌握ABAP代碼實(shí)現獲取服務(wù)器時(shí)間并格式化展示的方法,從而更好地滿(mǎn)足企業(yè)實(shí)際需求。    1、獲取服務(wù)器時(shí)間 獲取服務(wù)器時(shí)...

Linux服務(wù)器時(shí)間同步實(shí)踐指南

Linux服務(wù)器時(shí)間同步實(shí)踐指南

  對于Linux服務(wù)器,時(shí)間同步一直是非常重要的,因為它影響系統的許多方面,例如防火墻日志、證書(shū)、集群,以及其他系統和應用程序。因此在本指南中,將詳細闡述如何在Linux服務(wù)器上實(shí)現時(shí)間同步的最佳實(shí)踐。    1、使用NTP進(jìn)行時(shí)間同步 網(wǎng)絡(luò )時(shí)間協(xié)議(NTP)是一種可靠地同步系統時(shí)間的標準方式,并且在Linux服務(wù)器上廣泛使用。使用NTP有以下幾個(gè)步驟:   首先,需要安裝ntp服務(wù)...

Linux設置時(shí)間服務(wù)器地址的步驟和注意事項

Linux設置時(shí)間服務(wù)器地址的步驟和注意事項

  在Linux系統中,正確設置時(shí)間服務(wù)器地址對于保持系統時(shí)間的準確性至關(guān)重要。本文將從以下四個(gè)方面對Linux設置時(shí)間服務(wù)器地址的步驟和注意事項進(jìn)行詳細闡述:    1、查看當前時(shí)間服務(wù)器設置 在開(kāi)始設置時(shí)間服務(wù)器前,首先需要查看一下當前系統的時(shí)間服務(wù)器設置。   可以通過(guò)以下命令來(lái)查看:    timedatectl這個(gè)命...

Linux服務(wù)器時(shí)間對比:如何確保時(shí)間同步?

Linux服務(wù)器時(shí)間對比:如何確保時(shí)間同步?

  在Linux服務(wù)器中,時(shí)間同步對于保證系統的正常運行非常重要。本文將從以下4個(gè)方面對Linux服務(wù)器時(shí)間對比:如何確保時(shí)間同步進(jìn)行詳細闡述。    1、系統時(shí)間與硬件時(shí)間同步 系統時(shí)間和硬件時(shí)間是兩個(gè)非常重要的時(shí)間概念,系統時(shí)間指的是內核所維護的時(shí)間,硬件時(shí)間指的是服務(wù)器電腦中實(shí)際的時(shí)間。為保證時(shí)間同步,需要讓系統時(shí)間和硬件時(shí)間保持一致。在Linux服務(wù)器中,可以通過(guò)hwclock命令來(lái)進(jìn)行硬件時(shí)間和系統時(shí)間的同步。操作方...

Linux同步服務(wù)器時(shí)間的方法與步驟

Linux同步服務(wù)器時(shí)間的方法與步驟

  Linux服務(wù)器是一種廣泛運用的服務(wù)器系統,時(shí)間同步在服務(wù)器的日常維護過(guò)程中占有極其重要的地位。本篇文章將從NTP、Chrony和手動(dòng)同步三個(gè)方面,詳細闡述Linux同步服務(wù)器時(shí)間的方法與步驟,以幫助管理員更好地進(jìn)行服務(wù)器維護。    1、NTP NTP(Network Time Protocol)是目前廣泛使用的時(shí)間同步協(xié)議,也是Linux服務(wù)器同步時(shí)間的主要方法。   第一步,...

「如何以服務(wù)器時(shí)間為中心正確設置時(shí)間?」

「如何以服務(wù)器時(shí)間為中心正確設置時(shí)間?」

  文章概述:本文將詳細介紹如何以服務(wù)器時(shí)間為中心正確設置時(shí)間。我們將從以下四個(gè)方面進(jìn)行闡述:正確設置時(shí)區、使用網(wǎng)絡(luò )時(shí)間同步服務(wù)、確保系統硬件時(shí)鐘與軟件時(shí)鐘同步、手動(dòng)同步時(shí)間。希望本文對您正確設置時(shí)間有所幫助。    1、正確設置時(shí)區 時(shí)區是計算機操作系統中的一個(gè)非常重要的概念。時(shí)區的設置與服務(wù)器時(shí)間的同步密切相關(guān)。因此,必須先確保服務(wù)器所在的時(shí)區正確設置。否則,即使設置了正確的時(shí)間,仍然會(huì )導致系統時(shí)間不準確。...

GS5 GPS NTP時(shí)間服務(wù)器,全網(wǎng)授時(shí)最佳選擇

GS5 GPS NTP時(shí)間服務(wù)器,全網(wǎng)授時(shí)最佳選擇

  GS5 GPS NTP時(shí)間服務(wù)器是全網(wǎng)授時(shí)最佳選擇的產(chǎn)品之一。本文將從四個(gè)方面對其進(jìn)行詳細介紹,闡述GS5 GPS NTP時(shí)間服務(wù)器作為全網(wǎng)授時(shí)最佳選擇的原因。    1、技術(shù)優(yōu)勢 GS5 GPS NTP時(shí)間服務(wù)器采用北斗/雙模GPS/GLONASS衛星時(shí)鐘及時(shí)源,確保準確可靠的時(shí)間服務(wù)。該服務(wù)器有高精度時(shí)鐘震蕩和下行頻率智能自適應算法,可在良好或惡劣的室內外環(huán)境中提供穩定的時(shí)間信號。此外,服務(wù)器還支持NTP、PDC、SN...

Linux系統內服務(wù)器時(shí)間同步方案

Linux系統內服務(wù)器時(shí)間同步方案

  本文將圍繞Linux系統內服務(wù)器時(shí)間同步方案進(jìn)行詳細闡述。首先,整篇文章將從時(shí)間同步的重要性說(shuō)起,介紹Linux系統內默認的時(shí)間同步方案以及其不足之處,然后分別探討使用NTP、Chrony、Systemd-timedatectl等方案對服務(wù)器時(shí)間同步的優(yōu)缺點(diǎn)和應用,最后對全文進(jìn)行總結,提出一些具體的建議。    1、NTP方案 NTP(Network Time Protocol)是目前廣泛使用的一種網(wǎng)絡(luò )時(shí)間協(xié)議,它可以在I...

CSGO服務(wù)器維護今晚結束,玩家們準備好開(kāi)戰了嗎?

CSGO服務(wù)器維護今晚結束,玩家們準備好開(kāi)戰了嗎?

  近期,許多COSGO游戲玩家都備受關(guān)注的一件大事——COSGO游戲服務(wù)器的維護即將結束,玩家們準備好期待的開(kāi)戰了嗎?本文將從四個(gè)方面對此進(jìn)行詳細的闡述,分析COSGO這款經(jīng)典游戲在游戲服務(wù)器維護結束后會(huì )帶來(lái)哪些變化和影響。    1、COSGO游戲的背景和玩法介紹 COSGO是一款非常受歡迎的多人在線(xiàn)第一人稱(chēng)射擊游戲。它通過(guò)過(guò)關(guān)、擊殺對手等方式積累經(jīng)驗值,提升游戲等級和裝備等級,從而獲得更強的能力和更豐富的游戲體驗。在CO...

Linux服務(wù)器停機維護的時(shí)間安排和步驟詳解

Linux服務(wù)器停機維護的時(shí)間安排和步驟詳解

  本文將詳細闡述Linux服務(wù)器停機維護的時(shí)間安排和步驟,首先介紹為什么需要進(jìn)行服務(wù)器維護與停機,其次介紹停機維護時(shí)間的安排與步驟,然后分別從備份數據、升級系統、更新軟件和硬件維護四個(gè)方面進(jìn)行詳細的闡述,最后總結歸納。    1、為什么要進(jìn)行服務(wù)器維護與停機 作為一臺持續運行的服務(wù)器,會(huì )不可避免地存在各種問(wèn)題,并且配置、應用程序、操作系統等也會(huì )隨著(zhù)時(shí)間流逝而發(fā)生變化。因此,定期對服務(wù)器進(jìn)行維護和停機是保證服務(wù)器正常運行的關(guān)鍵...

“蘋(píng)果偽激活服務(wù)器放開(kāi)時(shí)間公布,萬(wàn)眾矚目6月初!”

“蘋(píng)果偽激活服務(wù)器放開(kāi)時(shí)間公布,萬(wàn)眾矚目6月初!”

  蘋(píng)果偽激活服務(wù)器放開(kāi)時(shí)間公布,萬(wàn)眾矚目6月初!近日,蘋(píng)果公司發(fā)布消息稱(chēng),將在6月初放開(kāi)偽激活服務(wù)器時(shí)間,此消息一發(fā)布立即引起了廣泛關(guān)注和討論。本文將從四個(gè)方面對此進(jìn)行詳細闡述。    1、偽激活服務(wù)器的概念 偽激活服務(wù)器是蘋(píng)果公司用于限制、解決非法盜版設備的軟件系統。當用戶(hù)的設備無(wú)法通過(guò)iTunes正常激活時(shí),可以通過(guò)偽激活服務(wù)器進(jìn)行激活,但是這種方式只能使用一段時(shí)間,蘋(píng)果公司會(huì )不定時(shí)封鎖服務(wù)器,因此偽激活設備只有短暫的使...

Linux下實(shí)時(shí)查看服務(wù)器時(shí)間的命令大全

Linux下實(shí)時(shí)查看服務(wù)器時(shí)間的命令大全

  文章概括:   本文將從多個(gè)方面詳細介紹Linux下實(shí)時(shí)查看服務(wù)器時(shí)間的命令大全,內容涵蓋四個(gè)方面:date命令、hwclock命令、ntpdate命令和timedatectl命令。通過(guò)本文的閱讀,讀者可以深入了解這些命令的使用方法和注意事項,從而更好地管理服務(wù)器時(shí)間。    1、date命令 date命令是Linux系統下最常用的查看時(shí)間的命令之一。它可以獲取系統當前的日期和時(shí)間,并且可以通過(guò)參數的方式...

DNF服務(wù)器全球開(kāi)服時(shí)間表大全

DNF服務(wù)器全球開(kāi)服時(shí)間表大全

  DNF是一個(gè)備受矚目的在線(xiàn)游戲,每一個(gè)DNF玩家都知道要對全球開(kāi)服時(shí)間表有一個(gè)統一的認識。隨著(zhù)DNF的不斷擴大,全球版的開(kāi)服時(shí)間也不斷更新,所以本文將詳細介紹DNF服務(wù)器全球開(kāi)服時(shí)間表大全。本文將從四個(gè)方面展開(kāi),分別是公告時(shí)間表、測試時(shí)間表、全球版本時(shí)間表和神話(huà)更新時(shí)間表。    1、公告時(shí)間表 對于任何DNF玩家,都需要知道公告的時(shí)間,以便了解最新的DNF信息。在公告時(shí)間表中,將列出公告的時(shí)間和內容。決定DNF運營(yíng)的一些...

Java代碼:獲取服務(wù)器時(shí)間并以此為中心的實(shí)現方法

Java代碼:獲取服務(wù)器時(shí)間并以此為中心的實(shí)現方法

  文章概括:   本文主要介紹了Java代碼中如何獲取服務(wù)器時(shí)間并以此為中心。首先講解了獲取系統時(shí)間的兩種方式,在此基礎上進(jìn)一步介紹了如何獲取服務(wù)器時(shí)間。接著(zhù),講解了如何將服務(wù)器時(shí)間作為基準,實(shí)現某些功能,例如定時(shí)任務(wù)。最后,給出了一個(gè)完整的實(shí)現代碼,方便讀者在項目中使用。    1、獲取服務(wù)器時(shí)間的方法 為了確保項目中各個(gè)模塊所使用的時(shí)間是具有一致性和準確性的,我們常常需要獲取服務(wù)器時(shí)間。那么,如何獲取服...

RM新时代官网网址|首入球时间