UDP Daytime服务客户端没有响应

时间:2013-11-21 17:18:36

标签: python python-2.7 network-programming udp

我正在努力学习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()

感谢您提前的时间

2 个答案:

答案 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说:

  1. NIST" DAYTIME"的用户强烈建议tcp端口13上的协议升级到网络时间协议,这提供了更高的准确性并且需要更少的网络带宽。 NIST时间客户端(nistime-32bit.exe)支持这两种协议。我们希望在2013年底之前用基于udp的版本替换此协议的tcp版本。
  2. 我读到它,因为他们目前只运行TCP 并将尽快切换到UDP 当他们绕过它时。

    http://tf.nist.gov/tf-cgi/servers.cgi

答案 1 :(得分:0)

有 3 个“时间”协议服务,每个服务在不同的端口上运行。

  • 端口 13 用于使用 TCP 或 UDP 协议 [1];
  • 端口 37 用于使用 TCP 或 UDP 协议 [2]
  • 端口 123 仅用于使用 UDP 的网络时间协议 (NTP)。 [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 响应包有四次定义如下:

  1. orig = 请求离开服务器时客户端的本地时间
  2. recv = 当请求从客户端到达时在服务器上的接收时间
  3. tx = 响应离开客户端时在服务器上的传输时间
  4. dest = 客户端收到 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