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

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

        使用Qt獲取NTP服務器時間是一個實用的功能,這樣可以使得程序在使用時更加準確,下面將會對這個功能進行詳細的闡述。

        

      1、QNetworkDatagram的使用

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

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

        使用QNetworkDatagram類來實現發送和接收數據包的代碼如下:

        ```

        QByteArray requestData(48, 0);

        requestData[0] = 0x1b; // 設置NTP協議版本

        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());

         // 對獲取的數據字節進行時間計算處理

        } else {

         qDebug() << "Request timeout";

        ```

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

        

      2、將時間戳轉化為人類可讀的時間

      獲取NTP服務器時間后,我們需要將時間戳轉化為人類可讀的時間。可以通過函數time_t ntohl(time_t netlong)將網絡字節序的32位無符號整數轉換為主機字節序的32位無符號整數。

        下面是將網絡字節序的64位時間戳轉換為人可讀的時間的代碼:

        ```

        QByteArray data; // 從服務器獲取的數據

        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;

        ```

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

        

      3、使用定時器獲取服務器時間

      我們可以使用Qt中的QTimer定時器類,并在定時器的槽函數中實現NTP協議的請求和計算NTP服務器時間的過程。

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

        ```

        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());

         // 進行時間戳處理

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

        

      4、使用并發框架多線程并發地獲取服務器時間

      對于高并發和網絡阻塞等問題,我們可以使用Qt提供的QThreadPool類實現多線程并發獲取NTP服務器時間。

        下面的代碼展示了如何使用QThreadPool和QRunnable類來實現多線程并發獲取NTP服務器時間:

        ```

        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());

         // 進行時間戳處理

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

         }

         ~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;

        };

        ```

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

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

        總結:

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

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

      標簽: 時頻百科

      相關文章

      《熱血江湖再起風云》——以《少年三國志》更新為契機,共筑新時代江湖傳奇

      《熱血江湖再起風云》——以《少年三國志》更新為契機,共筑新時代江湖傳奇

        《熱血江湖再起風云》是一款以《少年三國志》為主題的網絡游戲,通過更新內容,共筑新時代江湖傳奇。本文將從四個方面對該游戲進行詳細闡述。    1、游戲玩法創新 《熱血江湖再起風云》在更新中加入了大量新的游戲內容,如新的戰斗玩法、任務系統、劇情模式等,創新性地提升了游戲的可玩性。其中,任務系統是游戲最具特色的玩法。游戲中的任務分為主線任務和支線任務,每個任務都有獨特的劇情和場景,完成任務還能獲得豐富的獎勵。此外,游戲還加入了新...

      Linux服務器時間設置步驟詳解

      Linux服務器時間設置步驟詳解

        Linux 服務器時間是操作系統的重要參數之一,因為它在許多日志文件和其他應用程序中記錄時間戳。如果服務器時間不準確,則可能會導致許多問題,如日志數據不對齊,錯誤的時間戳等。因此,正確設置服務器時間非常關鍵。本文將基于此,為您提供詳細的 Linux 服務器時間設置步驟。    1、查看當前時間和時區設置 在 Linux 服務器上查看當前時間和時區可使用以下命令:   date...

      Linux服務器時間同步調整方法

      Linux服務器時間同步調整方法

        本文將對Linux服務器時間同步調整方法進行詳細闡述。首先,我們需要了解為什么需要同步時間。在Linux系統中,時間是非常重要的,許多系統功能都需要依賴于時間,比如系統日志、證書、安全驗證等等。如果服務器時間不準確,會導致很多問題,因此正確的時間同步方法可以極大地提高系統的可靠性和穩定性。    1、使用NTP協議進行時間同步 Network Time Protocol(網絡時間協議)可用于同步Internet上的所有計算...

      MT4服務器開服時間表及相關信息匯總

      MT4服務器開服時間表及相關信息匯總

        MT4是外匯交易市場最為流行的交易平臺之一,其安全穩定的服務器是交易者進行交易的基礎。本文以MT4服務器開服時間表及相關信息匯總為中心,探討MT4服務器的開服時間、服務器穩定性、升級維護及與經紀商之間的關系,幫助交易者更好地了解MT4服務器。    1、開服時間表 MT4服務器的開服時間表是交易者了解服務器開放時間的重要渠道。根據不同的經紀商,MT4服務器的開服時間可能會有所不同,但大多數交易商都遵循交易市場的開市時間。一...

      Dell服務器上門維修服務時間安排表

      Dell服務器上門維修服務時間安排表

        本文主要介紹"Dell服務器上門維修服務時間安排表",該服務時間安排表為用戶提供了詳細的時間表,用戶可根據表格中的時間來預約服務器上門維修服務。以下為本文對該服務時間安排表的詳細闡述。    1、服務時間安排表中包含哪些內容? "Dell服務器上門維修服務時間安排表"主要包含以下幾部分內容:服務模塊、服務項目名稱、服務類型、服務級別、工作日、上午、下午、晚上、是否可預約等。表格設計簡...

      Linux服務器NTP時間同步配置指南

      Linux服務器NTP時間同步配置指南

        本文將為讀者詳細介紹如何在Linux服務器上進行NTP時間同步配置,并且按照以下4個方面進行闡述:NTP時間同步及原理、NTP服務的安裝、配置及管理、Linux服務器的NTP同步及調整、NTP服務及其性能調優。希望本文能夠幫助讀者全面地掌握Linux服務器的NTP時間同步技術。    1、NTP時間同步及原理 NTP全稱為Network Time Protocol,是一種計算機網絡協議,用于同步各個計算機的系統時鐘。在Li...

      CDMA時間同步服務器:時間精確同步的解決方案

      CDMA時間同步服務器:時間精確同步的解決方案

        CDMA時間同步服務器是一種能夠提供高精度時間同步和時鐘頻率穩定性的解決方案。本文將從四個方面對CDMA時間同步服務器的解決方案進行詳細闡述。    1、CDMA時間同步服務器的工作原理 CDMA時間同步服務器的工作原理是通過將接收到的GPS時間信息與CDMA載波的本地時間信息進行比較和校正,從而實現高精度時間同步和時鐘頻率穩定性的控制。具體來說,CDMA時間同步服務器通過接收GPS信號,解算出GPS時間,并將該時間信息轉...

      IBMC服務器時間設置及優化方法

      IBMC服務器時間設置及優化方法

        IBMC服務器是企業級應用中高性能計算機的重要組成部分,對于服務器時間的準確設置和精細優化,可以保證系統運行效率和穩定性,為企業提供更好的服務。本文將從以下四個方面,詳細闡述IBMC服務器時間的設置和優化方法。    1、時間同步設置 時間同步是IBMC服務器時間設置中的基本內容,它保證了多臺服務器之間時間的一致性和準確性。在集群環境下,如果服務器之間的時間不同步,會導致系統運行異常,影響業務穩定性。因此,管理員需要在服務...

      Linux服務器時間同步服務詳解

      Linux服務器時間同步服務詳解

        Linux服務器時間同步服務是Linux系統使用的一個非常重要的服務,它可以確保服務器時間的精確同步,使得服務器性能得到更好的發揮。本文將從以下幾個方面進行詳細闡述:NTP時間同步服務、chrony時間同步服務、時間同步服務的設置與配置、時間同步服務的常見問題及解決方法。    1、NTP時間同步服務 網絡時間協議(NTP)時間同步服務是Linux系統中最常用的時間同步服務之一。它通過網絡同步服務器時間,確保服務器時間與國...

      2015年DNF服務器時間表及更新計劃

      2015年DNF服務器時間表及更新計劃

        在2015年,DNF的服務器時間表及更新計劃引起了許多玩家們的極大關注。為了正式開始游戲,玩家需要對于服務器時間表及更新計劃有一個清晰的了解,并且隨時跟進更新。在本文中,我們將從四個方面對2015年DNF服務器時間表及更新計劃進行詳細的闡述,幫助玩家們了解這些內容。    1、新的職業、新的副本 在2015年DNF的服務器時間表及更新計劃中,最重要的一件事情就是推出了新的職業與新的副本。新的職業包括了女鬼劍士、男漆黑之翼等...

      Linux系統如何使用NTP進行時間同步

      Linux系統如何使用NTP進行時間同步

         Linux系統如何使用NTP進行時間同步 本文將為大家介紹Linux系統如何使用NTP進行時間同步,以保證計算機時鐘的準確性和同步性。整個過程主要分為四個部分:NTP的安裝、配置、測試和維護。本文將會詳細地闡述每一部分的內容,讓您可以快速地掌握Linux系統如何使用NTP進行時間同步。    1、NTP的安裝 NTP是一款開源的時間同...

      AD服務器時間服務無法啟動的解決方法

      AD服務器時間服務無法啟動的解決方法

        本文主要介紹AD服務器時間服務無法啟動的解決方法。AD服務器是指運行Active Directory域服務的Windows服務器,其時間服務是維護服務器時間同步的重要組件。如果時間服務無法啟動,可能導致域內計算機時間同步錯誤,影響系統穩定性和安全性。本文將從以下四個方面為您講解AD服務器時間服務無法啟動的解決方法:    1、檢查Windows時間服務 Windows服務器上的時間服務是AD服務器時間服務的前提,因此,首先...

      Linux服務器超時時間優化技巧

      Linux服務器超時時間優化技巧

        超時時間是一個服務的重要參數,特別是在 Linux 服務器運維中,超時時間的設置直接影響到系統的穩定性和可靠性。本文將從四個方面,為大家詳細闡述如何優化 Linux 服務器的超時時間,保障系統的高效運行。    1、TCP 超時時間優化 TCP 超時時間是指當一個連接閑置一段時間后,內核就會發送一個探測數據包來檢測對端是否還存活。探測次數達到一定數量時,連接將被認為是失效的,從而發起關閉操作。Linux 內核默認的 TCP...

      Android系統設置時間服務器為中心

      Android系統設置時間服務器為中心

        在現今社會,掌握正確時間的重要性越來越凸顯,通過網絡時間服務器同步校準本地時間日益成為主流,Android作為智能手機的代表,也提供了修改時間服務器的功能,本文將從四個方面詳細闡述Android系統設置時間服務器的方法及其作用。    1、設置時間服務器的作用 設置時間服務器可以幫助我們將本地時間同步校準到一個正確的時間標準上,避免因為各種原因導致本地時間不準確,例如手機主動或被動關機、移動信號不好致使無法自動同步時間等等...

      《全球吃雞服務器活動時間表大公開!》

      《全球吃雞服務器活動時間表大公開!》

        隨著《絕地求生》(PUBG)這款游戲的全球人氣度越來越高,各種吃雞比賽也隨之而來。《全球吃雞服務器活動時間表大公開!》為廣大吃雞玩家提供了一個方便的查詢和了解全球吃雞比賽時間的平臺。本文將從四個方面詳細闡述這個時間表,包括查詢方式、參賽要求、比賽方式以及關注重點。    1、查詢方式 《全球吃雞服務器活動時間表大公開!》為廣大吃雞玩家提供了一個非常便利的查詢方式。玩家只需前往官方網站,點擊進入活動頁面,就可以看到全球各地的...

      主站蜘蛛池模板: 午夜视频在线观看免费完整版| 一级一级一片免费高清| 四虎在线免费视频| 亚洲男人天堂av| 久久精品人成免费| 亚洲精品无码久久久久久久 | 亚洲av无码成h人动漫无遮挡| 两个人日本WWW免费版| 亚洲无人区一区二区三区| 国产精品成人啪精品视频免费| 久久亚洲2019中文字幕| 亚洲第一页在线播放| 黄色永久免费网站| 亚洲人成色77777在线观看| 国产网站免费观看| 好猛好深好爽好硬免费视频 | 亚洲91av视频| 国产曰批免费视频播放免费s| 亚洲一卡2卡3卡4卡5卡6卡| 天堂亚洲免费视频| 国产色爽免费无码视频| 亚洲成a人片7777| 日韩免费高清视频网站| 好湿好大好紧好爽免费视频| 亚洲av无码乱码国产精品fc2| 67194熟妇在线永久免费观看| 亚洲av乱码一区二区三区按摩| 国产亚洲成归v人片在线观看 | 国产成人综合亚洲亚洲国产第一页| 最新国产乱人伦偷精品免费网站| 亚洲福利电影一区二区?| 日韩视频免费在线| 日韩av无码免费播放| 亚洲中文字幕日本无线码| 亚洲精品无码久久毛片| 2020因为爱你带字幕免费观看全集| 亚洲国产精品无码久久98| 国产亚洲欧洲精品| 永久免费AV无码网站在线观看| 最近更新免费中文字幕大全| 亚洲精品123区在线观看|