跨系统时间戳同步问题解决总结

一、问题背景

多个传感器分布在不同的主机上,且主机之间用局域网连接,但都与外网隔绝;在此情况下需要统一主机时间,否则传感器数据难以同步。

两台电脑需要时间同步:

  • 电脑A :Windows系统(10.*..102),作为时间戳发送方
  • 电脑B :Linux系统(10.*..101),作为时间戳接收方

内网环境,无法访问外网NTP服务器。


二、思考与排查过程

1. 最初尝试:NTP服务器方案

尝试将Linux配置为NTP服务器,Windows作为客户端同步。

Linux端配置:

bash 复制代码
# 安装ntp
sudo apt install ntp -y

# 配置/etc/ntp.conf
sudo tee /etc/ntp.conf <<EOF
server 127.127.1.0
fudge 127.127.1.0 stratum 10
restrict 10.111.34.0 mask 255.255.255.0 nomodify notrap
restrict 127.0.0.1
restrict ::1
restrict default ignore
driftfile /var/lib/ntp/drift
EOF

sudo systemctl restart ntp

Windows端同步:

cmd 复制代码
w32tm /config /manualpeerlist:"10.111.34.101" /syncfromflags:manual /reliable:yes /update
net stop w32time && net start w32time
w32tm /resync

2. 问题发现:网络通但同步失败

通过抓包发现网络是通的,但Windows不认Linux的NTP响应:

bash 复制代码
# Linux上抓包
sudo tcpdump -i any udp port 123 -vv

抓包结果显示Linux有回复,但包含[bad udp cksum],Windows可能因此丢弃数据包。

3. 方案转向:自定义Python脚本

既然标准NTP协议不行,改用简单的UDP自定义协议,Windows发送时间戳,Linux接收并设置时间。


三、最终解决方案

步骤1:Windows发送端脚本

创建 time_sender.py

python 复制代码
import socket
import struct
import time

def send_timestamp():
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    linux_ip = "10.111.34.101"
    port = 12345
    
    while True:
        timestamp = time.time()
        data = struct.pack('d', timestamp)
        sock.sendto(data, (linux_ip, port))
        print(f"发送: {timestamp:.3f} -> {time.ctime(timestamp)}")
        time.sleep(1)

if __name__ == "__main__":
    send_timestamp()

步骤2:Linux接收并设置时间脚本

创建 time_receiver.py

python 复制代码
import socket
import struct
import time
import os

def set_system_time(timestamp):
    date_str = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(timestamp))
    os.system(f"sudo date -s '{date_str}'")
    os.system("sudo hwclock --systohc 2>/dev/null")  # 同步硬件时钟
    print(f"时间已设置为: {date_str}")

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(("0.0.0.0", 12345))
print("等待接收时间戳...")

last_time = 0
while True:
    data, addr = sock.recvfrom(1024)
    win_time = struct.unpack('d', data)[0]
    
    print(f"\n收到来自 {addr[0]}:{win_time:.3f}")
    
    # 只在时间变化较大时设置(避免频繁设置)
    if abs(win_time - last_time) > 0.5:
        set_system_time(win_time)
        last_time = win_time

步骤3:Linux监控脚本(查看时间差)

创建 time_check.py

python 复制代码
import socket
import struct
import time

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(("0.0.0.0", 12345))
print("监控时间差...")

while True:
    data, addr = sock.recvfrom(1024)
    win_time = struct.unpack('d', data)[0]
    local_time = time.time()
    diff = win_time - local_time
    print(f"Windows: {win_time:.3f} | Linux: {local_time:.3f} | 差值: {diff:+.3f}秒")

四、运行流程

1. 在Linux上启动接收端(需要root权限)

bash 复制代码
sudo python3 time_receiver.py

2. 在Linux上另开终端启动监控(可选)

bash 复制代码
python3 time_check.py

3. 在Windows上启动发送端

cmd 复制代码
python time_sender.py

五、关键命令总结

用途 命令
Linux设置时间 sudo date -s "2026-03-12 20:30:00"
Linux查看时间 date
Windows设置时间 date 2026-03-12time 20:30:00
抓包诊断 sudo tcpdump -i any udp port 123 -vv
NTP服务状态 ntpq -p
Windows时间服务 w32tm /query /status

六、方案优势

  1. 简单可靠:绕过复杂的NTP协议,直接用UDP传输时间戳
  2. 完全可控:可以监控时间差,确保同步精度
  3. 内网可用:不依赖外网,适合封闭环境
  4. 跨平台:Python脚本可在Windows/Linux运行

这个方案最终成功解决了内网环境下Windows和Linux系统间的时间同步问题,实现了时间戳的对齐需求。

相关推荐
HLC++10 小时前
Linux的进程间通信
android·linux·服务器
华清远见IT开放实验室11 小时前
实验室建设案例 | 石家庄科技信息职业学院嵌入式实验室——从底层硬件到系统应用,一所应用型高校的嵌入式人才培养这样落地
linux·arm开发·stm32·嵌入式硬件·高校·实验室建设
groundhappy14 小时前
idalib安装和codex ida-mcp配置
linux·开发语言·python
通信小小昕15 小时前
Ubuntu 26.04 中文输入法安装
linux·运维·ubuntu
张小姐的猫16 小时前
【Linux】网络编程 —— HTTP协议(上)
linux·运维·服务器·网络·http·单例模式·策略模式
栩栩云生16 小时前
AI 写代码犯的错,早被写进了错题集
linux·安全·ai编程
imc.1117 小时前
linux基础IO
linux·运维·服务器
BelongPanda19 小时前
Linux Nginx 纯手动 Let‘s Encrypt 泛域名证书配置教程
linux·nginx
酷可达拉斯20 小时前
Linux操作系统-shell编程(0)
linux·运维·服务器·python·云计算
2301_7779983420 小时前
Linux中断机制:操作系统如何高效运行
linux·运维·服务器