Qt开源作品29-NTP服务器时间同步
一、前言
很多软件都有时间同步的功能,尤其是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);
}
三、效果图
四、开源主页
- 以上作品完整源码下载都在开源主页,会持续不断更新作品数量和质量,欢迎各位关注。
- 本开源项目已经成功升级到V2.0版本,分门别类,图文并茂,保你爽到爆。
- Qt开源武林秘籍开发经验,看完学完,20K起薪,没有找我!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
2019-06-07 Qt编写自定义控件23-广告轮播控件