【问题标题】:ntp client in pythonpython中的ntp客户端
【发布时间】:2020-03-03 18:23:35
【问题描述】:

我在 python 中编写了一个 ntp 客户端来查询时间服务器并显示时间,程序执行但没有给我任何结果。 我正在使用python的2.7.3集成开发环境,我的操作系统是Windows 7。 这是代码:

# File: Ntpclient.py
from socket import AF_INET, SOCK_DGRAM
import sys
import socket
import struct, time

# # Set the socket parameters 

host = "pool.ntp.org"
port = 123
buf = 1024
address = (host,port)
msg = 'time'


# reference time (in seconds since 1900-01-01 00:00:00)
TIME1970 = 2208988800L # 1970-01-01 00:00:00

# connect to server
client = socket.socket( AF_INET, SOCK_DGRAM)
client.sendto(msg, address)
msg, address = client.recvfrom( buf )

t = struct.unpack( "!12I", data )[10]
t -= TIME1970
print "\tTime=%s" % time.ctime(t)

【问题讨论】:

标签: python


【解决方案1】:

使用ntplib:

以下内容应该适用于 Python 2 和 3:

import ntplib
from time import ctime
c = ntplib.NTPClient()
response = c.request('pool.ntp.org')
print(ctime(response.tx_time))

输出:

Fri Jul 28 01:30:53 2017

【讨论】:

  • 非常感谢,我包含了库文件:从时间导入 ctime,它工作正常
  • 一个带有ntplib的小警告,它仍然有一个错误,它没有正确解析root_delaygithub.com/Tipoca/ntplib/issues/1
  • root_delay 是正确的。 (见本期最新评论)最精确的用法是本地时钟是否以这种方式通过偏移校准:fixed_time = response.offset + time.time()。这比来自时间服务器的简单时间戳更精确,因为来自 ntplib 的偏移被网络往返延迟的一半校正。
【解决方案2】:

这是对上述解决方案的修复,它为实现增加了几分之一秒并正确关闭了套接字。因为它实际上只是几行代码,我不想在我的项目中添加另一个依赖项,尽管ntplib 诚然在大多数情况下可能是要走的路。

#!/usr/bin/env python
from contextlib import closing
from socket import socket, AF_INET, SOCK_DGRAM
import struct
import time

NTP_PACKET_FORMAT = "!12I"
NTP_DELTA = 2208988800  # 1970-01-01 00:00:00
NTP_QUERY = b'\x1b' + 47 * b'\0'  

def ntp_time(host="pool.ntp.org", port=123):
    with closing(socket( AF_INET, SOCK_DGRAM)) as s:
        s.sendto(NTP_QUERY, (host, port))
        msg, address = s.recvfrom(1024)
    unpacked = struct.unpack(NTP_PACKET_FORMAT,
                   msg[0:struct.calcsize(NTP_PACKET_FORMAT)])
    return unpacked[10] + float(unpacked[11]) / 2**32 - NTP_DELTA


if __name__ == "__main__":
    print time.ctime(ntp_time()).replace("  ", " ")

【讨论】:

  • 旧线程,但这对我来说是一个很好、快速的解决方案,而不是试图弄清楚如何将模块添加到我的构建系统 (Petalinux)。
  • 如果您想知道'\x1b' + 47 * '\0' 代表什么:stackoverflow.com/a/26938508/1422096
  • 我喜欢这个答案,因为它的依赖性较小
  • UDP 套接字是无连接的,因此没有任何东西可以或需要关闭。当然,几分之一秒也适用于 ntplib 的原始解决方案。优点只是去掉了依赖
  • @hynekcer 感谢您对现代的更新!关于套接字:据我了解,无论如何它都应该关闭,只是为了节省本地资源。打开的套接字数量是有限的,对于长时间运行的进程,它们不应该被泄露。
【解决方案3】:

应该是

msg = '\x1b' + 47 * '\0' 

代替

msg = 'time'

但正如 Maksym 所说,您应该改用 ntplib。

【讨论】:

    【解决方案4】:
    msg = '\x1b' + 47 * '\0'
    .......
    t = struct.unpack( "!12I", msg )[10]
    

    【讨论】:

    • 虽然这可能会回答这个问题(我不确定),但通常最好包括一些关于为什么(以及如何)解决问题的解释。这尤其适用于回答一年多前提出的问题并且已经有a similar answer
    【解决方案5】:

    对不起,如果我的回答不能满足您的期望。我认为使用现有的解决方案是有意义的。 ntplib 是一个非常好的与 NTP 服务器一起工作的库。

    【讨论】:

      猜你喜欢
      • 2010-10-29
      • 2014-04-12
      • 2021-11-30
      • 1970-01-01
      • 2022-10-12
      • 1970-01-01
      • 2014-01-15
      • 2012-06-01
      • 2017-08-04
      相关资源
      最近更新 更多