当前位置: 首页 > news >正文

用C#(.NET8)开发一个NTP(SNTP)服务

完整源码,附工程下载,工程其实也就下面两个代码。
想在不能上网的服务器局域网中部署一个时间服务NTP,当然系统自带该服务,可以开启,本文只是分享一下该协议报文和能跑的源码。网上作为服务的源码不太常见,能见到不一定能跑起来,缺胳膊少脚的,分享代码一定要分享全。
先来效果图:
开启程序后,让win系统来同步本机时间效果如下:

添加图片注释,不超过 140 字(可选)

用通用客户端GuerrillaNtp来读,也没有问题:
在这里插入图片描述

添加图片注释,不超过 140 字(可选)
Fuck Shut Up,Show me the code
源码如下:
运行入口:

namespace NTP
{internal class Program{static void Main(string[] args){Console.WriteLine("Hello, NTP(SNTP)!");Console.WriteLine("本程序占用 UDP 123 端口,如遇冲突,请关闭系统自带时间服务 W32Time(Windows Time)");new SNTPServer().Start();Console.ReadLine();}}
}

主程序代码:

using System.Net.Sockets;
using System.Net;
using System.Buffers.Binary;namespace NTP
{/// <summary>/// 简单网络时间协议服务器/// </summary>public class SNTPServer{int port = 123;             //服务端口,NTP默认端口123bool stopFlag = false;      //通知后台线程停止消息循环的标识Thread tdServer;            //服务器后台监听线程/// <summary>/// 初始化一个简单网络时间协议服务器/// </summary>public SNTPServer(): this(123) { }/// <summary>/// 使用指定参数初始化一个简单网络时间协议服务器/// </summary>/// <param name="port">服务端口</param>public SNTPServer(int port){this.port = port;}/// <summary>/// 获取和设置服务端口号/// </summary>public int Port{get { return this.port; }set { this.port = value; }}/// <summary>/// 启动服务器/// </summary>public void Start(){if (tdServer == null || (!tdServer.IsAlive)){tdServer = new Thread(bgWork);tdServer.IsBackground = true;stopFlag = false;tdServer.Start();}}/// <summary>/// 停止服务器/// </summary>public void Stop(){stopFlag = true;}private void bgWork(){IPEndPoint iep;UdpClient udpclient;try{iep = new IPEndPoint(IPAddress.Any, port);udpclient = new UdpClient(iep);while (!stopFlag){if (udpclient.Available > 0){Console.WriteLine("收到一个请求:" + iep.Address + " 端口:" + iep.Port);byte[] buffer;IPEndPoint remoteipEP = new IPEndPoint(IPAddress.Any, port);buffer = udpclient.Receive(ref remoteipEP);if (buffer.Length >= 48){var bytesReceive = buffer.AsSpan();Console.WriteLine("收到数据[" + buffer.Length + "]:" + BitConverter.ToString(buffer));//记录收到请求的时间DateTime ReceiveTimestamp = DateTime.Now;//对方请求发出的时间,拿来显示看看DateTime? OriginateTimestamp = Decode(BinaryPrimitives.ReadInt64BigEndian(bytesReceive[40..]));//传输的都是国际时间,这里显示方便转成北京时间Console.WriteLine("对方请求发出时间:" + OriginateTimestamp?.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss.fff"));var Mode = 4;var VersionNumber = 3;var LeapIndicator = 0;var Stratum = 4;//Stratum 0是最高层级,代表原子钟、GPS接收器或其他高精度的时间源。var Poll = 0x0A;//NTP客户端向远程服务器发送时间请求的间隔(以秒为单位)。var Precision = 0xE9;buffer = new byte[48];var bytes = buffer.AsSpan();//LI(Leap Indicator):长度为2比特,值为“11”时表示告警状态,时钟未被同步。为其他值时NTP本身不做处理。//VN(Version Number):长度为3比特,表示NTP的版本号,目前的最新版本为3。//Mode:长度为3比特,表示NTP的工作模式。不同的值所表示的含义分别是:0未定义、1表示主动对等体模式、2表示被动对等体模式、3表示客户模式、4表示服务器模式、5表示广播模式或组播模式、6表示此报文为NTP控制报文、7预留给内部使用。//0x1C = 00 011 100bytes[0] = (byte)(((uint)LeapIndicator << 6) | ((uint)VersionNumber << 3) | (uint)Mode);bytes[1] = (byte)Stratum;bytes[2] = (byte)Poll;bytes[3] = (byte)Precision;BinaryPrimitives.WriteInt32BigEndian(bytes[4..], Encode(TimeSpan.Zero));//RootDelay = 0; Root Delay‌是指从主参考时钟到NTP服务器之间的往返时间延迟。它表示从主参考时钟到NTP服务器再返回的总体时间,通常以毫秒为单位。BinaryPrimitives.WriteInt32BigEndian(bytes[8..], Encode(TimeSpan.Zero));//RootDispersion = 0; Root Dispersion‌是指本地时钟相对于主参考时钟的最大误差。它表示NTP服务器时钟与主参考时钟之间的最大时间偏差,通常以毫秒为单位。BinaryPrimitives.WriteUInt32BigEndian(bytes[12..], BitConverter.ToUInt32(new byte[] { 0x41, 0x43, 0x54, 0x53 }, 0));//ReferenceIdentifierBinaryPrimitives.WriteInt64BigEndian(bytes[16..], Encode(DateTime.Now.ToUniversalTime()));//ReferenceTimestamp  系统时钟最后一次被设定或更新的时间//对方请求发出的时间 转成datetime 再转字节 会造成精度损失,【请求端会不认该报文】,应该返回原装字节,																						  //BinaryPrimitives.WriteInt64BigEndian(bytes[24..], Encode(OriginateTimestamp));bytes[24] = bytesReceive[40];bytes[25] = bytesReceive[41];bytes[26] = bytesReceive[42];bytes[27] = bytesReceive[43];bytes[28] = bytesReceive[44];bytes[29] = bytesReceive[45];bytes[30] = bytesReceive[46];bytes[31] = bytesReceive[47];BinaryPrimitives.WriteInt64BigEndian(bytes[32..], Encode(ReceiveTimestamp.ToUniversalTime()));//ReceiveTimestampBinaryPrimitives.WriteInt64BigEndian(bytes[40..], Encode(DateTime.Now.ToUniversalTime()));//TransmitTimestampConsole.WriteLine("返回数据[" + buffer.Length + "]:" + BitConverter.ToString(buffer));//系统NTP真实返回报文示例//buffer = new byte[] { 0x1C,0x04,0x00,0xE9,0x00,0x00,0x21,0xAA,0x00,0x00,0x16,0x0C,0x34,0xE7,0x72,0xB7,0xEB,0x0E, 0x62, 0x72,0xF7,0xCF,0x33,0xAF,0xEB,0x0E, 0x66, 0x3E, 0x79, 0x8B,0xB0,0x00,0xEB,0x0E, 0x66, 0x3E, 0x97, 0xCE,0xE6,0x82,0xEB,0x0E, 0x66, 0x3E, 0x97, 0xCF,0x51,0xE2 };udpclient.Send(buffer, buffer.Length, remoteipEP);}}}}catch (Exception e){Console.WriteLine(e.ToString());}}private const double FACTOR = 1L << 32;static readonly DateTime epoch = new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc) + TimeSpan.FromSeconds(1L << 32);static int Encode(TimeSpan time) => (int)(time.TotalSeconds * (1 << 16));static long Encode(DateTime? time) => time == null ? 0 : Convert.ToInt64((time.Value - epoch).TotalSeconds * (1L << 32));static DateTime? Decode(long bits) => bits == 0 ? null : epoch + TimeSpan.FromSeconds(bits / FACTOR);}
}

本代码亲自测试,木有问题.
工程下载:download.csdn.net/download/wudizhukk/90159750

相关文章:

用C#(.NET8)开发一个NTP(SNTP)服务

完整源码&#xff0c;附工程下载&#xff0c;工程其实也就下面两个代码。 想在不能上网的服务器局域网中部署一个时间服务NTP&#xff0c;当然系统自带该服务&#xff0c;可以开启&#xff0c;本文只是分享一下该协议报文和能跑的源码。网上作为服务的源码不太常见&#xff0c;…...

Mybatis能执行一对一、一对多的关联查询吗?都有哪些实现方式,以及它们之间的区别

MyBatis 是一个用于简化数据库操作的框架&#xff0c;它可以帮助开发人员通过映射语句轻松执行 SQL 查询&#xff0c;并且能够方便地实现对象与数据库表之间的映射。MyBatis 支持一对一、一对多和多对多等关联查询。下面我们来探讨一下 MyBatis 如何实现一对一、一对多的关联查…...

ABAP SQL 取日期+时间最新的一条数据

我们在系统对接的时候&#xff0c;外部系统可能会推送多个数据给到我们。 我们 SAP 系统的表数据中日期和时间是作为主键的&#xff0c;那么如果通过 ABAP SQL 取到最新日期的最新时间呢。 解决方案&#xff1a; 方式 1&#xff1a;SELECT MAX 可以通过两个 SELECT MAX 来取…...

【Rust自学】4.3. 所有权与函数

4.3.0 写在正文之前 在学习了Rust的通用编程概念后&#xff0c;就来到了整个Rust的重中之重——所有权&#xff0c;它跟其他语言都不太一样&#xff0c;很多初学者觉得学起来很难。这个章节就旨在让初学者能够完全掌握这个特性。 本章有三小节&#xff1a; 所有权&#xff1…...

【Redis分布式锁】高并发场景下秒杀业务的实现思路(集群模式)

一、什么是分布式锁 我们在上篇文章中实现了单机模式下的秒杀业务。其中采用了synchronized加锁来解决各种线程安全问题。而synchronized关键字是依赖于单机的JVM&#xff0c;在集群模式下&#xff0c;每个服务器都有独立的JVM&#xff0c;如果此时还采用synchronized关键字加…...

用docker快速安装电子白板Excalidraw绘制流程图

注&#xff1a;本文操作以debian12.8 最小化安装环境为host系统。 一、彻底卸载原有的残留 apt-get purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras 二、设置docker的安装源 # Add Dockers official G…...

使用Turtle库实现,鼠标左键绘制路径,用鼠标右键结束绘制,小海龟并沿路径移动

使用Turtle库实现&#xff0c;鼠标左键绘制路径&#xff0c;用鼠标右键结束绘制&#xff0c;小海龟并沿路径移动 Turtle库是Python标准库的一部分&#xff0c;它提供了一种基于命令的图形绘制方式。Turtle模块通过一个“海龟”&#xff08;Turtle&#xff09;对象在屏幕上移动…...

人工智能入门是先看西瓜书还是先看花书?

在人工智能入门时&#xff0c;关于先看《机器学习》&#xff08;西瓜书&#xff09;还是先看《深度学习》&#xff08;花书&#xff09;的问题&#xff0c;实际上取决于个人的学习目标和背景。 《机器学习》&#xff08;西瓜书&#xff09;由周志华教授撰写&#xff0c;是一本…...

winform中屏蔽双击最大化或最小化窗体(C#实现),禁用任务管理器结束程序,在需要屏蔽双击窗体最大化、最小化、关闭

winform中屏蔽双击最大化或最小化窗体(C#实现)&#xff0c;禁用任务管理器结束程序,在需要屏蔽双击窗体最大化、最小化、关闭 protected override void WndProc(ref Message m){#region 处理点击窗体标题栏放大缩小问题&#xff0c;禁用点击窗体标题栏放大缩小//logger.Info($&…...

进程内存转储工具|内存镜像提取-取证工具

1.内存转储&#xff0c;内存转储&#xff08;Memory Dump&#xff09;是将计算机的物理内存&#xff08;RAM&#xff09;内容复制到一个文件中的过程&#xff0c;这个文件通常被称为“内存转储文件”或“核心转储文件”&#xff08;Core Dump&#xff09;,内存转储的主要目的是…...

数据结构day5:单向循环链表 代码作业

一、loopLink.h #ifndef __LOOPLINK_H__ #define __LOOPLINK_H__#include <stdio.h> #include <stdlib.h>typedef int DataType;typedef struct node {union{int len;DataType data;};struct node* next; }loopLink, *loopLinkPtr;//创建 loopLinkPtr create();//…...

(OCPP服务器)SteVe编译搭建全过程

注意&#xff1a;建议使用3.6.0&#xff0c;我升级到3.7.1&#xff0c;并没有多什么新功能&#xff0c;反而电表的实时数据只能看到累计电能了&#xff0c;我回退了就正常&#xff0c;数据库是兼容的&#xff0c;java版本换位java11&#xff0c;其他不变就好 背景&#xff1a;…...

Mybatis分页插件的使用问题记录

项目中配置的分页插件依赖为 <dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.1.7</version></dependency>之前的项目代码编写分页的方式为&#xff0c;通过传入的条件…...

36. Three.js案例-创建带光照和阴影的球体与平面

36. Three.js案例-创建带光照和阴影的球体与平面 实现效果 知识点 Three.js基础 WebGLRenderer WebGLRenderer 是Three.js中最常用的渲染器&#xff0c;用于将场景渲染到网页上。 构造器 new THREE.WebGLRenderer(parameters)参数类型描述parametersobject可选参数&#…...

CentOS 7 安装、测试和部署FastDFS

目录 FastDFS环境搭建 安装 libfastcommon 库 安装FastDFS 查看编译后的文件 FastDFS配置 FastDFS启动 启动tracker服务 启动storage服务 查看storage是否已经注册到了tracker下 查看存储文件的目录 FastDFS重启 FastDFS关闭 使用fdfs_test进行测试 修改client.co…...

全志H618 Android12修改doucmentsui选中图片资源详情信息

背景: 由于当前的文件管理器在我们的产品定义当中,某些界面有改动的需求,所以需要在Android12 rom中进行定制以符合当前产品定义。 需求: 进入file文件管理器后,点击选中图片资源,选中功能按钮,获取信息,不显示“调试信息(仅开发者)”;现状是,获取信息,显示“调试信…...

【083】基于51单片机智能烘手器【Proteus仿真+Keil程序+报告+原理图】

☆、设计硬件组成&#xff1a;51单片机最小系统LCD1602液晶显示DS18B20温度传感器TCRT5000红外感应传感器AT24C02存储芯片风扇加热片继电器LED灯按键设置。 1、设计采用STC89C51/52、AT89C51/52、AT89S51/52作为主控芯片&#xff1b; 2、系统采用DS18B20温度传感器感应当前环…...

uniApp使用腾讯地图提示未添加maps模块

uniApp使用腾讯地图&#xff0c;打包提示未添加maps模块解决方案 这是报错信息&#xff0c;在标准基座运行的时候是没问题的&#xff0c;但是打包后会提示未添加&#xff0c;可以通过在mainfest里面把地图插件上腾讯地图的key更换高德地图的key&#xff0c;定位服务可以继续用腾…...

未来趋势系列 篇五:自主可控科技题材解析和股票梳理

文章目录 系列文章自主可控科技题材分析国产算力信创(信息技术应用创新)华为鸿蒙军工信息化半导体芯片卫星互联网工业软件股票梳理系列文章 未来趋势系列 篇一:AI题材解析和股票梳理 未来趋势系列 篇一(加更):AI医疗题材解析和股票梳理 未来趋势系列 篇二:HBM题材解析和…...

Springboot 学习 之 logback-spring.xml 日志压缩 .tmp 临时文件问题

文章目录 前言功能简述1. 自定义日志文件名2. 归档规则 && 压缩2.1. 归档配置2.2. 归档压缩2.3. 日志格式 && 编码 现象原因解决办法 前言 在 Springboot 应用中&#xff0c;默认使用 logback-spring.xml 配置日志相关 功能简述 1. 自定义日志文件名 <fi…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

用docker来安装部署freeswitch记录

今天刚才测试一个callcenter的项目&#xff0c;所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

Web 架构之 CDN 加速原理与落地实践

文章目录 一、思维导图二、正文内容&#xff08;一&#xff09;CDN 基础概念1. 定义2. 组成部分 &#xff08;二&#xff09;CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 &#xff08;三&#xff09;CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 &#xf…...

iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈

在日常iOS开发过程中&#xff0c;性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期&#xff0c;开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发&#xff0c;但背后往往隐藏着系统资源调度不当…...

掌握 HTTP 请求:理解 cURL GET 语法

cURL 是一个强大的命令行工具&#xff0c;用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中&#xff0c;cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...

Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?

Pod IP 的本质与特性 Pod IP 的定位 纯端点地址&#xff1a;Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址&#xff08;如 10.244.1.2&#xff09;无特殊名称&#xff1a;在 Kubernetes 中&#xff0c;它通常被称为 “Pod IP” 或 “容器 IP”生命周期&#xff1a;与 Pod …...

基于单片机的宠物屋智能系统设计与实现(论文+源码)

本设计基于单片机的宠物屋智能系统核心是实现对宠物生活环境及状态的智能管理。系统以单片机为中枢&#xff0c;连接红外测温传感器&#xff0c;可实时精准捕捉宠物体温变化&#xff0c;以便及时发现健康异常&#xff1b;水位检测传感器时刻监测饮用水余量&#xff0c;防止宠物…...