对某个远程服务器启用和设置NTP服务(Windows系统)
打开注册表
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer
将 Enabled 的值设置为 1,这将启用NTP服务器功能。

防火墙开放UDP 123端口

打开“服务”应用(可以在开始菜单搜索“服务”),找到“Windows Time”服务。右键点击“Windows Time”服务,选择“重启”。

执行以下命令来配置服务器模式并重启时间服务:
w32tm /config /reliable:YES /update
net stop w32time
net start w32time

客户端上面,输入以下命令,替换你自己的NTP服务端IP即可,如果显示类似以下的时间输出,说明是正常的。
w32tm /stripchart /computer:ip地址 /samples:5 /dataonly

编写程序,进行时间同步
引用包Wesky.Net.OpenTools ,版本选择1.0.6或以上版本。

该包的自述文件内容供参考:
https://www.nuget.org/packages/Wesky.Net.OpenTools/1.0.6#readme-body-tab

在程序里面使用,以下测试内容供参考。其中,ntpServer可以是ip地址也可以是ntp服务器的域名地址或者互联网ntp服务器地址等。获取时间默认端口号没指定的话是123,如果要指定,只需要在参数里面新增端口号参数即可。

static void Main(string[] args)
{
string ntpServer = "ip";
Console.WriteLine($"当前时间:\r\n{ DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss ms")}");
DateTime time = NtpClient.GetNtpServerTime(ntpServer);
Console.WriteLine($"获取到的时间为:\r\n {time.ToString("yyyy/MM/dd HH:mm:ss ms")}");
NtpClient.SetSystemTime(time);
Console.WriteLine($"更改后的系统时间:\r\n{ DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss ms")}");
Console.ReadLine();
}
获取ntp服务器时间核心代码解析如下:
public static DateTime GetNtpServerTime(string ntpServer,int ntpPort=123)
{
byte[] ntpData = new byte[NtpDataLength];
ntpData[0] = 0x1B;
var addresses = Dns.GetHostAddresses(ntpServer);
IPEndPoint ipEndPoint = new IPEndPoint(addresses[0], ntpPort);
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
{
socket.Connect(ipEndPoint);
socket.Send(ntpData);
socket.Receive(ntpData);
}
ulong intPart = BitConverter.ToUInt32(ntpData, 40);
ulong fractPart = BitConverter.ToUInt32(ntpData, 44);
intPart = SwapEndianness(intPart);
fractPart = SwapEndianness(fractPart);
var milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000L);
DateTime networkDateTime = new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds((long)milliseconds);
return networkDateTime.ToLocalTime();
}
该文章在 2024/5/30 15:15:20 编辑过