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

    }

}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Web日志/招聘网站/电商大数据项目样例【实时/离线】

Web服务器日志分析项目 业务分析 业务背景 ​ 某大型电商公司&#xff0c;产生原始数据日志某小时达4千五万条&#xff0c;一天日志量月4亿两千万条。 主机规划 &#xff08;可略&#xff09;日志格式&#xff1a; 2017-06-1900:26:36101.200.190.54 GET /sys/ashx/ConfigH…

预处理指令详解

前言 上一节我们了解了文件操作的相关内容&#xff0c;本节我们来了解一下预处理指令&#xff0c;那么废话不多说&#xff0c;我们正式开始今天的学习 预定义符号 在C语言中&#xff0c;设置了一些预定义的符号&#xff0c;可以供我们直接使用&#xff0c;预定义符号是在程序…

一场人生的风险控制,商业社会识人指南

一、资料前言 本套社会识人资料&#xff0c;大小679.94M&#xff0c;共有37个文件。 二、资料目录 识人的终极目的&#xff1a;一整场人生的风险控制.pdf 信任的搭建&#xff1a;更多的时间与维度.pdf 没有搞不定的人&#xff01;角色人格与全面人格.pdf 政治不正确的正确…

程序员为什么不能一次性写好,需要一直改Bug?

程序员为什么不能一次性写好&#xff0c;需要一直改Bug&#xff1f; 我有一问&#xff1a; 你为什么不上清华呢&#xff0c;高考答满分不就行了&#xff1f; 程序员在软件开发过程中可能会遇到需要不断修改Bug的情况&#xff0c;这主要是由以下几个原因造成的&#xff1a; 复杂…

Linux简单介绍

Linux简单介绍 编译器VMware虚拟机Ubuntu——LinuxOS为什么使用LinuxOS&#xff1f; 目录结构Windows目录结构Linux操作系统home是不是家目录&#xff1f; Linux常用命令终端命令行提示符与权限切换命令tab 作用&#xff1a;自动补全上下箭头pwd命令ls命令mkdir命令touch命令rm…

智能革命:ChatGPT3.5与GPT4.0的融合,携手DALL·E 3和Midjourney开启艺术新纪元

迷图网(kk.zlrxjh.top)是一个融合了顶尖人工智能技术的多功能助手&#xff0c;集成了ChatGPT3.5、GPT4.0、DALLE 3和Midjourney等多种智能系统&#xff0c;为用户提供了丰富的体验。以下是对这些技术的概述&#xff1a; ChatGPT3.5是由OpenAI开发的一个自然语言处理模型&#x…

第17章 反射机制

一 反射(Reflection)的概念 1.1 反射的出现背景 Java程序中&#xff0c;所有的对象都有两种类型&#xff1a;编译时类型和运行时类型&#xff0c;而很多时候对象的编译时类型和运行时类型不一致。 Object obj new String(“hello”); obj.getClass() 例如&#xff1a;某些变…

C++多线程:单例模式与共享数据安全(七)

1、单例设计模式 单例设计模式&#xff0c;使用的频率比较高&#xff0c;整个项目中某个特殊的类对象只能创建一个 并且该类只对外暴露一个public方法用来获得这个对象。 单例设计模式又分懒汉式和饿汉式&#xff0c;同时对于懒汉式在多线程并发的情况下存在线程安全问题 饿汉…

深入理解计算机系统 家庭作业 2.75

/* 书中的公式是w位的公式(mod 就是为了截断成w位),我们现在做的是2w位中的前w位 注意书上这句话:由于模运算符,所有带有权重和的项都丢掉 对应到本题 该项除以后还是超过了2w位所以被丢弃了,因为题目说了只有2w位 这个式子除以就是我们想要的最终结果 函数signed_high_p…

前端学习<四>JavaScript基础——03-常量和变量

常量&#xff08;字面量&#xff09;&#xff1a;数字和字符串 常量也称之为“字面量”&#xff0c;是固定值&#xff0c;不可改变。看见什么&#xff0c;它就是什么。 常量有下面这几种&#xff1a; 数字常量&#xff08;数值常量&#xff09; 字符串常量 布尔常量 自定义…

Vol.34 Good Men Project:一个博客网站,每月90万访问量,通过付费订阅和广告变现

今天给大家分享的案例网站是&#xff1a;Good Men Project&#xff0c;这是一个专门针对男性成长的博客网站&#xff0c;内容包括人际关系、家庭、职业发展等话题。 它的网址是&#xff1a;The Good Men Project - The Conversation No One Else Is Having 流量情况 我们先看…

高分卫星助力台湾省花莲县地震应急救援

4月3日7时58分&#xff0c;在台湾省花莲县海域&#xff08;北纬23.81度&#xff0c;东经121.74度&#xff09;发生7.3级地震&#xff0c;震源深度12公里。接中国地震局地震预测研究所应急需求&#xff0c;国家航天局对地观测与数据中心&#xff08;以下简称“中心”&#xff09…

C#仿OutLook的特色窗体设计

目录 1. 资源图片准备 2. 设计流程&#xff1a; &#xff08;1&#xff09;用MenuStrip控件设计菜单栏 &#xff08;2&#xff09;用ToolStrip控件设计工具栏 &#xff08;3&#xff09;用StatusStrip控件设计状态栏 &#xff08;4&#xff09;ImageList组件装载树节点图…

SQLyog连接数据库8.0版本解析错误问题解决方案

问题描述&#xff1a; 解决方案&#xff1a; alter userrootlocalhostidentified with mysql_native_password by 密码; 再次连接就可以了。

实现顺序表的增删查改

现在让我们探索数据结构这个美妙的世界吧&#xff01; 概念介绍 线性表是具有相同特性的数据元素的有限序列。线性表是一种在实际运用中广泛运用的线性结构&#xff0c;如线性表&#xff0c;栈&#xff0c;队列&#xff0c;字符串等。 顺序表的本质是数组&#xff0c;实现了…

js的事件冒泡、捕获、委托

事件不仅存在js中&#xff0c;也存在在其他语言中&#xff0c;js事件背后的主要思想是能够在特定事件发生时运行代码。 先普及一个概念&#xff0c;什么是事件处理程序&#xff1f; 事件处理程序就像一个特殊的通用遥控器&#xff0c;可以执行某些操作&#xff0c;例如更改电…

java自动化-03-04java基础之数据类型举例

1、需要特殊注意的数据类型举例 1&#xff09;定义float类型&#xff0c;赋值时需要再小数后面带f float num11.2f; System.out.println(num1);2&#xff09;定义double类型&#xff0c;赋值时直接输入小数就可以 3&#xff09;另外需要注意&#xff0c;float类型的精度问题…

鸿蒙开发就业前景到底怎么样?

随着科技的不断进步&#xff0c;鸿蒙操作系统的推出为开发者们带来了新的机遇和挑战。鸿蒙&#xff0c;作为华为自主研发的操作系统&#xff0c;旨在为消费者提供更为流畅、安全的智能设备体验。那么&#xff0c;鸿蒙开发就业前景如何呢&#xff1f; 一、鸿蒙操作系统的优势 …

探索--------------redis缓存三大问题及解决方案

目录 一、redis的三大缓存问题 1、缓存穿透 1.1 问题描述 1.2缓存穿透发生的条件 1.3缓存穿透发生的原因 1.4解决方案 2、缓存雪崩 2.1问题描述 2.2解决缓存雪崩问题的方法有&#xff1a; 3、缓存击穿 &#xff08;热点数据集中失效&#xff09; 3.1问题描述 3.2缓…

SpringBoot快速入门笔记(3)

文章目录 一、MybatisPlus1、ORM2、添加依赖3、全局配置4、Navicat5、UserController6、CRUD操作7、BaseMapper8、两个注解 二、多表查询1、模拟用户订单2、通过用户查相关订单3、UserMapperNew4、查询订单和所属用户5、OrderMapper6、OrderController 三、条件查询四、分页查询…