Qt教程之实现NTP时间同步工具代码

0 638
索鸟 2021-03-15
需要:0索币

很多软件都有时间同步的功能,尤其是Qt在嵌入式设备上的,有时候还有很多是没有UI界面的程序,而硬件上有个时钟,时间久了难免没有电,需要从服务器来同步时间来保证本地的时间是正确的,不然本地记录的一些日志的时间都是不正确的,很多还可能是1970年的。
NTP同步时间是个标准的协议,使用的端口是123端口,这个端口很牛逼,居然霸占了123这个端口,碉堡!使用NTP服务同步时间,需要设置个时间服务器IP地址,这个地址可以网上找到很多的,微软自带的那个有时候行有时候不行,因为默认用的UDP协议,所以是不可靠的,有丢包的可能,建议选择一些国内的时间服务器,比如一些大学的时间服务器,还是比较准确可靠的。

## 二、代码思路
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);
}
```

## 三、效果图

原文地址:http://www.qtcn.org/bbs/read-htm-tid-88698-ds-1.html

回帖
  • 消灭零回复
相关主题
2020年最新最新Kubernetes视频教程(K8s)教程 2
程序员转型之制作网课变现,月入过万告别996 1
索鸟快传2.0发布啦 1
两个不同网络的电脑怎么实现文件的互相访问呢? 1
网盘多账号登录软件 1
Java实战闲云旅游项目基于vue+element-ui 1
单点登录技术解决方案基于OAuth2.0的网关鉴权RSA算法生成令牌 1
QT5获取剪贴板上文本信息QT设置剪贴板内容 1
springboot2实战在线购物系统电商系统 1
python web实战之爱家租房项目 1
windows COM实用入门教程 1
C++游戏开发之C++实现的水果忍者游戏 1
计算机视觉库opencv教程 1
node.js实战图书管理系统express框架实现 1
C++实战教程之远程桌面远程控制实战 1
相关主题
PHP7报A non well formed numeric value encountered 0
Linux系统下关闭mongodb的几种命令分享 0
mongodb删除数据、删除集合、删除数据库的命令 0
Git&Github极速入门与攻坚实战课程 0
python爬虫教程使用Django和scrapy实现 0
libnetsnmpmibs.so.31: cannot open shared object file 0
数据结构和算法视频教程 0
redis的hash结构怎么删除数据呢? 0
C++和LUA解析器的数据交互实战视频 0
mongodb errmsg" : "too many users are authenticated 0
C++基础入门视频教程 0
用30个小时精通C++视频教程可能吗? 0
C++分布式多线程游戏服务器开发视频教程socket tcp boost库 0
C++培训教程就业班教程 0
layui的util工具格式时间戳为字符串 0
C++实战教程之远程桌面远程控制实战 1
网络安全培训视频教程 0
LINUX_C++软件工程师视频教程高级项目实战 0
C++高级数据结构与算法视频教程 0
跨域问题很头疼?通过配置nginx轻松解决ajax跨域问题 0