QT实现NTP功能

一.NTP基础

1.NTP定义

NTP(Network Time Protocol,网络时间协议)是由RFC 1305定义的时间同步协议,用于分布式设备(比如电脑、手机、智能手表等)进行时间同步,避免人工校时的繁琐和由此引入的误差,方便快捷地实现多设备时间同步。

NTP校时服务基于UDP传输协议进行报文传输,工作端口默认为123/udp。

NTP使用协调世界时(UTC)以极高的精度同步计算机时钟时间,例如在局域网(LAN)中低至1毫秒,在互联网上则在数十毫秒内。

2.NTP 网络结构

服务器按层级关系连接,每一级称为一个层数(stratum),如主时间服务器层数为 stratum 1,二级时间服务器层数为 stratum 2,以此类推。时钟层数越大,准确性越低。

在局域网(LAN)中低至1毫秒,在互联网上则在数十毫秒内。

3.NTP 报文格式

NTP有两种不同类型的报文,一种是时钟同步报文,另一种是控制报文。控制报文仅用于需要网络管理的场合,它对于时钟同步功能来说并不是必需的,这里不做介绍。

时钟同步报文封装在UDP报文中,其格式如图所示:

各主要字段解释如下:

LI (Leap Indicator) : 长度为2比特,值为“11”时表示告警状态,时钟未被同步。为其他值时NTP本身不做处理。

VN (Version Number): 长度为3比特,表示NTP的版本号.

Mode:长度为3比特,表示NTP的工作模式。不同的值所表示的含义分别是:0未定义、1表示主动对等体模式、2表示被动对等体模式、3表示客户模式、4表示服务器模式、5表示广播模式或组播模式、6表示此报文为NTP控制报文、7预留给内部使用。

Stratum:系统时钟的层数,取值范围为1~16,它定义了时钟的准确度。层数为1的时钟准确度最高,准确度从1到16依次递减,层数为16的时钟处于未同步状态,不能作为参考时钟。

Poll:轮询时间,即两个连续NTP报文之间的时间间隔。

Precision:系统时钟的精度。

Root Delay:本地到主参考时钟源的往返时间。

Root Dispersion:系统时钟相对于主参考时钟的最大误差。

Reference Identifier:参考时钟源的标识。

Reference Timestamp:系统时钟最后一次被设定或更新的时间。

Originate Timestamp:NTP请求报文离开发送端时发送端的本地时间。

Receive Timestamp:NTP请求报文到达接收端时接收端的本地时间。

Transmit Timestamp:应答报文离开应答者时应答者的本地时间。

Authenticator:验证信息。

其中,NTP发送和接收的报文数据包类似,通常只需要前48个字节就能进行授时和校时服务。下面分别是抓包获取的NTP请求数据包和回复数据包示例(仅前48个字节):

请求数据包:

1B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ------------头部

D0 AF 5F F5 23 D7 08 00---------------Originate Timestamp ()出发时间戳有效位为8 bytes

回复数据包:

1C 02 00 EC 00 00 06 EA 00 00 0C A2 C0 A8 33 CA----数据包头部,共16 bytes

D0 AF 5E A3 F5 BD 72 BC---------------Reference Timestamp

D0 AF 5F F5 23 D7 08 00---------------Originate Timestamp ()

D0 AF 61 D7 CD 2E F9 11---------------Receive Timestamp ()

D0 AF 61 D7 CD 2F F4 BA---------------Transmit Timestamp ()

收到数据包后,接收端本地再产生一个时间戳()。

这里,每个返回数据前4字节为秒的整数部分,后4字节为秒的小数部分。

4.NTP时钟服务器

下面补充一些常用的NTP时钟服务器:

名称            地址

北斗授时服务     114.255.121.193

清华TUNA协会     ntp.tuna.tsinghua.edu.cn

国家NTP授时     ntp.ntsc.ac.cn

中国NTP快速授时  cn.ntp.org.cn

教育网NTP授时  edu.ntp.org.cn

更多NTP授时服务器请查看:

http://www.ntp.org.cn/pool

https://dns.iui.im/ntp/

pool.ntp.org: the internet cluster of ntp servers

二.QT代码示例

  1. UDP请求包

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), QTime(0, 0, 0));

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

}

  1. UDP接收报文及解析

void NtpClient::readData()

{

    QByteArray newTime;

    QDateTime epoch(QDate(1900, 1, 1), QTime(0, 0, 0));

    QDateTime unixStart(QDate(1970, 1, 1), QTime(0, 0, 0));

    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;

    uint secs = seconds - epoch.secsTo(unixStart);

    dateTime.setTime_t(secs);

    udpSocket->disconnectFromHost();

    if (dateTime.isValid()) {

        Q_EMIT receiveTime(dateTime);

    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/515022.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【漏洞复现】极简云 download.php 接口处存在任意文件读取漏洞

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

什么是线程安全、怎么保证线程安全

目录 什么是线程安全 多线程编程中的三个核心概念 JMM内存模型 JMM内存模型怎么实现原子性、可见性 怎么保证线程安全 什么是线程安全 当多个线程访问一个对象时&#xff0c;如果不用考虑这些线程在运行时环境下的调度和交替执行&#xff0c;也不需要进行额外的同步&#x…

Rust---复合数据类型之结构体

目录 结构体的使用输出结果 结构体简化创建结构体更新语法元组结构体单元结构体&#xff08;unit struct&#xff09;结构体中的引用使用#[derive(Debug)]再次介绍 代码综合展示 与元组不同的是&#xff0c;结构体可以为内部的每个字段起一个富有含义的名称&#xff0c;因此无需…

基于SpringBoot+Vue的汽车租赁管理系统的设计和实现【附源码】

1、系统演示视频&#xff08;演示视频&#xff09; 2、需要交流和学习请联系

vivado适用于 UltraScale 和 UltraScale+ 器件的 eFUSE 寄存器访问和编程

FUSE_DNA &#xff1a; 唯一的器件 DNA 每个 UltraScale 器件都有唯一的器件 ID &#xff0c; 称为器件 DNA &#xff0c; 且赛灵思已将此 DNA 编程到器件中。用户无法对 FUSE_DNA 进行编程。 UltraScale 器件具有 96 位 DNA 。您可在 Vivado Design Suite Tcl 控制台中…

Matlab梁单元有限元编程:铁木辛柯梁VS欧拉梁

专栏导读 作者简介&#xff1a;工学博士&#xff0c;高级工程师&#xff0c;专注于工业软件算法研究本文已收录于专栏&#xff1a;《有限元编程从入门到精通》本专栏旨在提供 1.以案例的形式讲解各类有限元问题的程序实现&#xff0c;并提供所有案例完整源码&#xff1b;2.单元…

openplc Linux 地址映射io,读写驱动数据等使用记录

1. 上一篇记录 openplc使用C语言文件读写驱动实现基本流程。 openPLC_Editor C语言编程 在mp157 arm板上调用io等使用记录_openplc c 编程-CSDN博客 2. 下面通过映射地址的方式控制io和读写驱动数据。 在runtime 环境的 hardware 硬件配置中 选择 python on Linux(PSM)&#…

成为先进企业应该从用飞书开始,还是应该从裁员开始?

点击文末“阅读原文”即可参与节目互动 剪辑、音频 / 卷圈 运营 / SandLiu 卷圈 监制 / 姝琦 封面 / 姝琦Midjourney 产品统筹 / bobo 大家都觉得飞书不行了&#xff0c;我们反而不这么看。 众所周知&#xff0c;飞书最近裁员的消息在业界引起了巨大的反响&#xff0c;大…

基于SSM+Jsp+Mysql的快递管理系统

开发语言&#xff1a;Java框架&#xff1a;ssm技术&#xff1a;JSPJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包…

62、服务攻防——框架安全CVE复现SpringStrutsLaravelThinkphp

文章目录 常见语言开发框架&#xff08;主流&#xff09;&#xff1a; PHP&#xff1a;ThinkPHP、Laravel、YIIJAVA&#xff1a;Spring、SpringbootPython&#xff1a;FlaskJavaScript&#xff1a;Vue.js、Node.js 框架判断()&#xff1a; 通过插件Wappalyzer&#xff08;可能…

练手项目层初阶1—《详解静态版本——通讯录管理系统》

文章目录 &#x1f6a9;前言&#x1f50a; 项目需求&#x1f4da; 项目知识点包含&#x1f9e9;项目框架&#x1f4dd;框架拆解分析✨Struct_book.h 头文件解析✨Struct_book.c文件解析✨test_book.c文件解析 &#x1f4fa;演示效果&#x1f680;完整代码 &#x1f6a9;前言 俗…

联想 Y9000P 连接网线速度慢 的 问题解决

参考帖子&#xff1a;求助&#xff0c;拯救者Y9000P 2022 i73060版本 有线网非常慢 无线网正常【笔记本吧】_百度贴吧 问题原因&#xff1a; 网卡驱动版本不对。不能用Win11版&#xff0c;要用Win10版。 问题解决&#xff1a; 1、卸载原驱动 2、下载Win10 驱动 并安装 下载…

C语言——常用库函数的使用及模拟实现

C语言编译系统为使用者提供了很多的预定义库函数。用户在编写程序时&#xff0c;可以直接调用这些库函数。这里选择了一些常用的库函数&#xff0c;简单介绍各个函数的使用方法&#xff1a; 字符串函数 字符串函数函数分为长度不受限制的字符串函数&#xff0c;和长度受限制的…

手搓链表(java)(不完整)

手搓链表&#xff08;java&#xff09;&#xff08;不完整&#xff09; 文章目录 手搓链表&#xff08;java&#xff09;&#xff08;不完整&#xff09;前言一、代码1.MyLinkedList类&#xff1a;2.测试类&#xff1a; 总结 前言 提示&#xff1a;以下是本篇文章正文内容&…

Git 术语及中英文对照

完毕&#xff01;&#xff01;感谢您的收看 ----------★★历史博文集合★★---------- 我的零基础Python教程&#xff0c;Python入门篇 进阶篇 视频教程 Py安装py项目 Python模块 Python爬虫 Json Xpath 正则表达式 Selenium Etree CssGui程序开发 Tkinter Pyqt5 列表元组字…

保姆级教程——VLAN综合实验(不同VLAN通过动态路由访问外网)

前言&#xff1a; 部署了VLAN的传统交换机不能实现不同VLAN间的二层报文转发&#xff0c;因此必须引入路由技术来实现不同VLAN间的通信。VLAN路由可以通过二层交换机配合路由器来实现&#xff0c;也可以通过三层交换机来实现 VLAN间通信的限制 每个VLAN都是一个独立的…

vue 使用自定义标签URL Protocol 调用本地exe 并传参

创建注册表文件reg&#xff0c;并运行 里面的路径需要替换成实际exe的绝对路径 Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\App] "URL:App Protocol Handler" "URL Protocol""" [HKEY_CLASSES_ROOT\App\DefaultIcon] &qu…

启动mysql

删除C:\Program Files (x86)\MySQL\MySQL Server 5.7这个路径下的data文件夹&#xff0c;这个很难删除&#xff0c;因为一开机&#xff0c;mysql的某些服务就启动了&#xff0c;每次重新启动mysql之前&#xff0c;都要删除这个文件夹 因为这个文件夹在后端执行一些我们看不到的…

pycharm打包python文件为exe文件(图文教程)

1.安装pyinstaller库 pip3 install pyinstaller 2.使用pyinstaller 打包文件 首先确保Terminal命令行中&#xff0c;你的路径和你的项目是同一个路径 我的项目就是放在golden_dev中的。 3.命令行内输入打包代码 pyinstaller -F -w gold_miner.py gold_miner.py 是我的项目…

HomePlug AV

目录 HomePlug AV的基本概念基本术语网络概念网络实例 HomePlug AV物理层&#xff08;PHY&#xff09;HomePlug AV OFDM收发器架构PHY的调制模式FC调制和ROBO调制物理层的特点OFDM频域/时域转换开窗/槽式OFDM信号和噪声PHY发送控制——信道自适应PHY帧格式&#xff08;Symbol&a…