本帖最后由 xy6538 于 2026-1-30 20:40 编辑
教师机时间同步服务:解决云桌面学生机时间混乱问题(附源码)
背景与痛点
我们学校有两个机房,使用的是云桌面系统。在“禁网上课”期间(即断开外网,仅教师机联网),学生电脑的时间经常严重不准——有的慢几分钟,有的快几小时,甚至还有停留在出厂日期(如 2009 年)的情况。
这导致:
- 考试系统时间错误
- 日志记录混乱
- 软件授权验证失败
- 学生作业提交时间异常
由于学生端无法访问外网 NTP 服务器,常规自动校时又不是太稳定。于是就有了这套基于教师机的内网时间同步方案,已在两个不同网段的机房稳定运行超过一年,效果显著!
解决方案概述
- 教师机:作为时间服务端,开机时自动从公网 NTP 服务器(如阿里云、Windows 时间服务器等)校准自身系统时间,并启动一个轻量级 HTTP 服务。
- 学生机:开机后自动运行客户端脚本,定期(默认每 5 分钟)从教师机获取准确时间,并设置本地系统时间。
- 无需外网:学生机完全不需要联网,只需能访问教师机 IP 即可。
- 跨网段支持:已在两个不同子网的机房部署验证。
核心代码
服务端(教师机)
import os
import socket
import datetime
import ntplib
from flask import Flask
from waitress import serve
app = Flask(__name__)
NTP_SERVERS = [
"ntp.aliyun.com",
"time.windows.com",
"pool.ntp.org",
"cn.pool.ntp.org",
"time.apple.com"
]
def sync_system_time_from_ntp():
for server in NTP_SERVERS:
try:
print(f" 正在尝试从 {server} 获取标准时间...")
client = ntplib.NTPClient()
response = client.request(server, version=3, timeout=2)
ntp_time = datetime.datetime.utcfromtimestamp(response.tx_time)
local_time = ntp_time + datetime.timedelta(hours=8)
local_time_str = local_time.strftime("%Y-%m-%d %H:%M:%S")
print(f"[+] 成功从 {server} 获取标准时间: {local_time_str}")
os.system(f'date {local_time.strftime("%Y-%m-%d")}')
os.system(f'time {local_time.strftime("%H:%M:%S").replace(":", ".")}')
return
except Exception as e:
print(f"[-] 从 {server} 获取时间失败: {e}")
print("[-] 所有NTP服务器均无法访问,跳过时间同步")
@app.route('/gettime')
def get_time():
current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
return current_time
if __name__ == '__main__':
print(" 正在从网络校准时间...")
sync_system_time_from_ntp()
ip = socket.gethostbyname(socket.gethostname())
print(f" 教师机时间服务已启动,地址: http://{ip}:5000/gettime")
serve(app, host='0.0.0.0', port=5000)
客户端(学生端)
import requests
import time
import os
import ctypes
import locale
TEACHER_IP = "10.100.10.100" # 替换为教师机IP
PORT = 5000
INTERVAL = 300 # 5分钟同步一次
def get_system_locale():
try:
windll = ctypes.windll.kernel32
locale_name = locale.windows_locale[windll.GetUserDefaultUILanguage()]
return locale_name
except Exception as e:
print(f"[-] 获取区域设置失败: {e}")
return None
def sync_time():
try:
url = f"http://{TEACHER_IP}:{PORT}/gettime"
response = requests.get(url, timeout=5)
if response.status_code == 200:
server_time = response.text.strip()
print("收到教师机时间:", server_time)
date_str, time_str = server_time.split()
locale_name = get_system_locale()
if locale_name and locale_name.startswith('zh'):
mmddyyyy = date_str
else:
mmddyyyy = '/'.join(date_str.split('-')[1:] + [date_str.split('-')[0]])
hhmmss = time_str.replace(":", ".")
os.system(f'date {mmddyyyy}')
os.system(f'time {hhmmss}')
except Exception as e:
print("同步失败:", str(e))
if __name__ == "__main__":
while True:
sync_time()
time.sleep(INTERVAL)
依赖安装
[Python] 纯文本查看 复制代码 pip install flask waitress ntplib requests
优势总结
- 轻量简单:仅依赖 HTTP 接口,无复杂协议
- 高兼容性:支持 Windows 7/10/11(已实测)
- 自动容错:教师机多 NTP 源轮询,保障时间准确性
- 零成本部署:纯 Python 实现,无需额外服务器
说明
- 由于涉及到教师机IP地址(见学生端代码部分),所以这里就不提供成品
exe 文件。
- 本项目源于真实教学场景,现已稳定运行一年以上。欢迎有类似需求的老师使用或改进!
- 学生端打包时,记得带上
--noconsole 参数,不显示控制台窗口,适合后台运行。
|