首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >简单的SNTP python脚本

简单的SNTP python脚本
EN

Stack Overflow用户
提问于 2016-09-13 09:39:02
回答 3查看 4K关注 0票数 6

我需要帮助完成以下脚本:

代码语言:javascript
复制
import socket
import struct
import sys
import time

NTP_SERVER = '0.uk.pool.ntp.org'
TIME1970 = 2208988800L

def sntp_client():
    client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    data = str.encode('\xlb' + 47 * '\0')
    client.sendto(data, (NTP_SERVER, 123))
    data, addr = client.recvfrom(1024)
    if data:
        print('Response received from:', addr)
    t = struct.unpack('!12I', data)[10]
    t -= TIME1970
    print('\tTime: %s' % time.ctime(t))

if __name__ == '__main__':
    sntp_client()

预期产出:

代码语言:javascript
复制
Response received from: ('80.82.244.120', 123)
      Time: Tue Sep 13 14:49:38 2016

问题是程序没有提供任何输出。它看起来像是在:

代码语言:javascript
复制
data, addr = client.recvfrom(1024)

我希望有人能帮我这个忙。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-01-27 08:17:29

下面是第二版 of Python网络编程手册的工作脚本

代码语言:javascript
复制
import socket, struct, sys, time

NTP_SERVER = '0.uk.pool.ntp.org'
TIME1970 = 2208988800

def sntp_client():
    client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    data = '\x1b' + 47 * '\0'
    client.sendto(data.encode('utf-8'), (NTP_SERVER, 123))
    data, address = client.recvfrom(1024)
    if data: print('Response received from:', address)
    t = struct.unpack('!12I', data)[10] - TIME1970
    print('\tTime = %s' % time.ctime(t))

if __name__ == '__main__':
    sntp_client()
票数 4
EN

Stack Overflow用户

发布于 2019-12-18 13:56:11

应该指出,接受答案忽略了时间戳的分数部分,例如,见IETF RFC5905,第13页。一个代码片段,包括它可能看起来像

代码语言:javascript
复制
import socket
import struct
import datetime

NTP_SERVER = '0.uk.pool.ntp.org'
NTP_DELTA = 2208988800 # given as system epoch (e.g. 1970-1-1) minus NTP epoch (1900-1-1) in [s]

with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as client:
    data = '\x1b' + 47 * '\0'
    client.sendto(data.encode('utf-8'), (NTP_SERVER, 123))
    data, _ = client.recvfrom(256)
    tx_s, tx_f = struct.unpack('!12I', data)[10:12] # seconds and fractional seconds
    tx_timestamp = (tx_s + float(tx_f)/2**32) - NTP_DELTA
    
print(datetime.datetime.fromtimestamp(tx_timestamp, datetime.timezone.utc)) 
# e.g.
# 2019-12-18 13:02:14.029521+00:00 # Note: UTC used here for output!

还要记住,这只返回传输时间戳(tx;服务器发送数据包时的时间)。如果您寻找毫秒,往返延迟可能是显着的(例如,参见链接RFC5905的第29页)。

Sidenote:套接字文档建议在with上下文中打开套接字,以便在不再需要时正确关闭它。

票数 3
EN

Stack Overflow用户

发布于 2016-10-19 02:26:22

编写的脚本没有任何问题,您需要寻找服务器可能没有响应您的另一个原因,例如防火墙设置。我自己的python脚本几乎完全相同:

代码语言:javascript
复制
    #!/bin/env python

    import socket
    import struct
    import sys
    import time

    TIME1970 = 2208988800L      # Thanks to F.Lundh

    pow2_31 = pow(2,31)
    pow2_32 = pow(2,32)
    pow2_16 = pow(2,16)

    if len(sys.argv) < 2:
        sys.stderr.write("Usage : " + sys.argv[0] + " <SNTP server>")
        exit(1)

    server = sys.argv[1]

    client = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
    data = '\x1b' + 47 * '\0'
    time_start = time.time()
    try:
        client.sendto( data, ( server, 123 ))
        client.settimeout(2)
    except:
        print "server <%s> not recognized" % (server)
        exit(2)
    try:
        data, address = client.recvfrom( 1024 )
    except socket.timeout:
        print "timed out"
        exit(3)

    if data:
        time_reply = (time.time() - time_start) * 1000
        print 'received %d bytes  from %s in %d ms :' % (len(data), address, time_reply)
        upacket = struct.unpack( '!48B', data )
        print upacket

用法:

代码语言:javascript
复制
$ ./sntp_client.py 0.uk.pool.ntp.org
代码语言:javascript
复制
received 48 bytes  from ('83.170.75.28', 123) in 154 ms :
(28, 3, 3, 236, 0, 0, 1, 171, 0, 0, 3, 0, 20, 139, 208, 232, 219, 177, 86, 148, 230, 192, 1, 15, 0, 0, 0, 0, 0, 0, 0, 0, 219, 177, 88, 27, 60, 214, 85, 212, 219, 177, 88, 27, 60, 238, 157, 39)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39466780

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档