diff --git a/README.md b/README.md index 7d0cf14..4709552 100644 --- a/README.md +++ b/README.md @@ -27,4 +27,5 @@ | 24 | qwtdemo | qwt的源码版本,无需插件,直接源码集成到你的项目即可 | | 25 | buttondefence | 通用按钮地图效果 | | 26 | mouseline | 鼠标定位十字线 | -| 27 | email | 邮件发送工具 | \ No newline at end of file +| 27 | email | 邮件发送工具 | +| 27 | ntpclient | NTP服务器时间同步 | \ No newline at end of file diff --git a/ntpclient/frmntpclient.cpp b/ntpclient/frmntpclient.cpp new file mode 100644 index 0000000..0f26473 --- /dev/null +++ b/ntpclient/frmntpclient.cpp @@ -0,0 +1,27 @@ +#pragma execution_character_set("utf-8") + +#include "frmntpclient.h" +#include "ui_frmntpclient.h" +#include "ntpclient.h" + +frmNtpClient::frmNtpClient(QWidget *parent) : QWidget(parent), ui(new Ui::frmNtpClient) +{ + ui->setupUi(this); + connect(NtpClient::Instance(), SIGNAL(receiveTime(QDateTime)), this, SLOT(receiveTime(QDateTime))); +} + +frmNtpClient::~frmNtpClient() +{ + delete ui; +} + +void frmNtpClient::on_btnGetTime_clicked() +{ + NtpClient::Instance()->setNtpIP(ui->txtNtpIP->text().trimmed()); + NtpClient::Instance()->getDateTime(); +} + +void frmNtpClient::receiveTime(const QDateTime &dateTime) +{ + ui->txtTime->setText(dateTime.toString("yyyy-MM-dd HH:mm:ss")); +} diff --git a/ntpclient/frmntpclient.h b/ntpclient/frmntpclient.h new file mode 100644 index 0000000..1b34afc --- /dev/null +++ b/ntpclient/frmntpclient.h @@ -0,0 +1,27 @@ +#ifndef FRMNTPCLIENT_H +#define FRMNTPCLIENT_H + +#include +#include + +namespace Ui { +class frmNtpClient; +} + +class frmNtpClient : public QWidget +{ + Q_OBJECT + +public: + explicit frmNtpClient(QWidget *parent = 0); + ~frmNtpClient(); + +private: + Ui::frmNtpClient *ui; + +private slots: + void on_btnGetTime_clicked(); + void receiveTime(const QDateTime &dateTime); +}; + +#endif // FRMNTPCLIENT_H diff --git a/ntpclient/frmntpclient.ui b/ntpclient/frmntpclient.ui new file mode 100644 index 0000000..ac6e8db --- /dev/null +++ b/ntpclient/frmntpclient.ui @@ -0,0 +1,68 @@ + + + frmNtpClient + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 10 + 10 + 321 + 48 + + + + + + + NTP服务器 + + + + + + + 133.100.11.8 + + + + + + + + 0 + 0 + + + + 获取时间 + + + + + + + 返回时间 + + + + + + + + + + + + diff --git a/ntpclient/main.cpp b/ntpclient/main.cpp new file mode 100644 index 0000000..1c6bfde --- /dev/null +++ b/ntpclient/main.cpp @@ -0,0 +1,31 @@ +#pragma execution_character_set("utf-8") + +#include "frmntpclient.h" +#include +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + a.setFont(QFont("Microsoft Yahei", 9)); + +#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0)) +#if _MSC_VER + QTextCodec *codec = QTextCodec::codecForName("gbk"); +#else + QTextCodec *codec = QTextCodec::codecForName("utf-8"); +#endif + QTextCodec::setCodecForLocale(codec); + QTextCodec::setCodecForCStrings(codec); + QTextCodec::setCodecForTr(codec); +#else + QTextCodec *codec = QTextCodec::codecForName("utf-8"); + QTextCodec::setCodecForLocale(codec); +#endif + + frmNtpClient w; + w.setWindowTitle("Ntp校时"); + w.show(); + + return a.exec(); +} diff --git a/ntpclient/ntpclient.cpp b/ntpclient/ntpclient.cpp new file mode 100644 index 0000000..ae7387e --- /dev/null +++ b/ntpclient/ntpclient.cpp @@ -0,0 +1,107 @@ +#include "ntpclient.h" +#include "qmutex.h" +#include "qudpsocket.h" + +QScopedPointer NtpClient::self; +NtpClient *NtpClient::Instance() +{ + if (self.isNull()) { + static QMutex mutex; + QMutexLocker locker(&mutex); + if (self.isNull()) { + self.reset(new NtpClient); + } + } + + return self.data(); +} + +NtpClient::NtpClient(QObject *parent) : QObject(parent) +{ + ntpIP = "202.120.2.101"; + + udpSocket = new QUdpSocket(this); + connect(udpSocket, SIGNAL(connected()), this, SLOT(sendData())); + connect(udpSocket, SIGNAL(readyRead()), this, SLOT(readData())); +} + +void NtpClient::sendData() +{ + qint8 LI = 0; + qint8 VN = 3; + qint8 MODE = 3; + qint8 STRATUM = 0; + qint8 POLL = 4; + qint8 PREC = -6; + QDateTime epoch(QDate(1900, 1, 1)); + qint32 second = quint32(epoch.secsTo(QDateTime::currentDateTime())); + + qint32 temp = 0; + QByteArray timeRequest(48, 0); + timeRequest[0] = (LI << 6) | (VN << 3) | (MODE); + timeRequest[1] = STRATUM; + timeRequest[2] = POLL; + timeRequest[3] = PREC & 0xff; + timeRequest[5] = 1; + timeRequest[9] = 1; + timeRequest[40] = (temp = (second & 0xff000000) >> 24); + temp = 0; + timeRequest[41] = (temp = (second & 0x00ff0000) >> 16); + temp = 0; + timeRequest[42] = (temp = (second & 0x0000ff00) >> 8); + temp = 0; + timeRequest[43] = ((second & 0x000000ff)); + + udpSocket->write(timeRequest); +} + +void NtpClient::readData() +{ + QByteArray newTime; + QDateTime epoch(QDate(1900, 1, 1)); + QDateTime unixStart(QDate(1970, 1, 1)); + + while (udpSocket->hasPendingDatagrams()) { + newTime.resize(udpSocket->pendingDatagramSize()); + udpSocket->read(newTime.data(), newTime.size()); + }; + + QByteArray transmitTimeStamp ; + transmitTimeStamp = newTime.right(8); + quint32 seconds = transmitTimeStamp.at(0); + quint8 temp = 0; + + for (int i = 1; i <= 3; i++) { + seconds = (seconds << 8); + temp = transmitTimeStamp.at(i); + seconds = seconds + temp; + } + + QDateTime dateTime; + dateTime.setTime_t(seconds - epoch.secsTo(unixStart)); + +#ifdef __arm__ +#ifdef arma9 + dateTime = dateTime.addSecs(60 * 60 * 8); +#endif +#endif + udpSocket->disconnectFromHost(); + + //有些时候返回的数据可能有误或者解析不正确,导致填充的时间不正确 + if (dateTime.isValid()) { + emit receiveTime(dateTime); + } +} + +void NtpClient::setNtpIP(const QString &ntpIP) +{ + if (this->ntpIP != ntpIP) { + this->ntpIP = ntpIP; + } +} + +void NtpClient::getDateTime() +{ + udpSocket->abort(); + udpSocket->connectToHost(ntpIP, 123); +} diff --git a/ntpclient/ntpclient.h b/ntpclient/ntpclient.h new file mode 100644 index 0000000..7f1e475 --- /dev/null +++ b/ntpclient/ntpclient.h @@ -0,0 +1,54 @@ +#ifndef NTPCLIENT_H +#define NTPCLIENT_H + +/** + * Ntp校时类 作者:feiyangqingyun(QQ:517216493) 2017-2-16 + * 1:可设置Ntp服务器IP地址 + * 2:收到时间信号发出 + */ + +#include +#include +class QUdpSocket; + +#ifdef quc +#if (QT_VERSION < QT_VERSION_CHECK(5,7,0)) +#include +#else +#include +#endif + +class QDESIGNER_WIDGET_EXPORT NtpClient : public QObject +#else +class NtpClient : public QObject +#endif + +{ + Q_OBJECT +public: + static NtpClient *Instance(); + explicit NtpClient(QObject *parent = 0); + +private: + static QScopedPointer self; + QString ntpIP; + QUdpSocket *udpSocket; + +private slots: + void readData(); + void sendData(); + +signals: + //收到时间返回 + void receiveTime(const QDateTime &dateTime); + +public slots: + //设置NTP服务器IP + void setNtpIP(const QString &ntpIP); + + //获取日期时间 + void getDateTime(); + +}; + +#endif // NTPCLIENT_H diff --git a/ntpclient/ntpclient.pro b/ntpclient/ntpclient.pro new file mode 100644 index 0000000..7140f06 --- /dev/null +++ b/ntpclient/ntpclient.pro @@ -0,0 +1,23 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2019-02-16T15:08:47 +# +#------------------------------------------------- + +QT += core gui network + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = ntpclient +TEMPLATE = app +DESTDIR = $$PWD/../bin +CONFIG += warn_off + +SOURCES += main.cpp +SOURCES += frmntpclient.cpp +SOURCES += ntpclient.cpp + +HEADERS += frmntpclient.h +HEADERS += ntpclient.h + +FORMS += frmntpclient.ui