我正在努力学习W. Chun的Python核心应用程序编程:
2-6。日间服务。使用socket.getservbyname()确定UDP协议下“daytime”服务的端口号。检查文档中的getservbyname()以获取确切的用法语法(即socket.getservbyname。 doc )。现在编写一个发送虚拟消息并等待回复的应用程序。收到服务器的回复后,将其显示在屏幕上。
我的代码显然不正确,我无法理解原因:
#!/usr/bin/env python
from socket import *
HOST = 'time.nist.gov'
PORT = getservbyname('daytime', 'udp')
BUFSIZ = 1024
ADDR = (HOST, PORT)
udpCliSock = socket(AF_INET, SOCK_DGRAM)
while True:
udpCliSock.sendto('dummy message', ADDR)
data, ADDR = udpCliSock.recvfrom(BUFSIZ)
if not data:
break
print data
udpCliSock.close()
感谢您提前的时间
答案 0 :(得分:1)
我认为您的代码完全有效,但没有UDP服务 at time.nist.gov。
如果先使用udpCliSock.connect(ADDR),然后再使用send()
sendto(),您将收到connection refused
错误。这通常
意味着没人在听。
如果使用sendto()(无连接UDP ...),则会禁止此错误。
我根据cpp-lib(https://github.com/gewesp/cpp-lib)和我自己的UDP类测试了你的代码 只要服务器实际回复,它就能很好地工作。
NIST说:
我读到它,因为他们目前只运行TCP 并将尽快切换到UDP 当他们绕过它时。
答案 1 :(得分:0)
有 3 个“时间”协议服务,每个服务在不同的端口上运行。
1.使用“白天”服务(端口 13)
time.nist.gov 上的白天 UDP 服务(端口 13)似乎被禁用或防火墙阻止了 UDP 数据包响应。
但是,您可以调用 DAYTIME TCP 服务来获取当前时间:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "time.nist.gov"
port = 13
s.connect((host, port))
while True:
data = s.recv(1024)
if data:
print(data.decode())
else:
break
s.close()
输出:
59373 21-06-08 17:03:08 50 0 0 535.1 UTC(NIST) *
2.使用“时间”服务(端口 37)
UDP 端口 37 上的 TIME 服务以二进制格式返回一个 32 位无符号整数。您可以将 1-Jan-1900 的相对时间(以秒为单位)转换为日期时间对象。
port = 37
host = "time.nist.gov"
sock = socket.socket(socket.AF_INET, # Internet
socket.SOCK_DGRAM) # UDP
msg = "ask for time"
sock.sendto(msg.encode(), (host , port ))
data, addr = sock.recvfrom(1024)
print("received message: %s" % data)
sock.close()
# convert 32-bit unsigned integer in binary format to an integer
seconds = int.from_bytes(data, byteorder='big')
print(f"seconds={seconds}")
dt = datetime(1900, 1, 1) + timedelta(seconds=seconds)
print("rcv=", dt)
print("now=", datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M:%S'))
输出:
received message: b'\xe4j13'
seconds=3832164659
rcv=2021-06-08 18:21:43
now=2021-06-08 18:21:43
3.使用网络时间协议 (NTP) 服务(端口 123)
NTP 响应包有四次定义如下:
NTP 与其他时间协议的不同之处在于,通过这 4 次,它能够计算时间偏移(两个时钟之间的时间差)和往返延迟(或延迟)。
import ntplib
client = ntplib.NTPClient()
server = "time.nist.gov"
resp = client.request(server, version=3)
print("offset", resp.offset)
print("delay", resp.delay)
print("orig_time:", datetime.utcfromtimestamp(resp.orig_time).strftime('%Y-%m-%d %H:%M:%S.%f'))
print("recv_time:", datetime.utcfromtimestamp(resp.recv_time).strftime('%Y-%m-%d %H:%M:%S.%f'))
print("tx_time :", datetime.utcfromtimestamp(resp.tx_time).strftime('%Y-%m-%d %H:%M:%S.%f'))
print("dest_time:", datetime.utcfromtimestamp(resp.dest_time).strftime('%Y-%m-%d %H:%M:%S.%f'))
输出:
offset 0.004678010940551758
delay 0.06687116622924805
orig_time: 2021-06-10 19:07:52.410973
recv_time: 2021-06-10 19:07:52.449087
tx_time : 2021-06-10 19:07:52.449089
dest_time: 2021-06-10 19:07:52.477846