【问题标题】:UDP Daytime service client getting no responseUDP 日间服务客户端无响应
【发布时间】:2013-11-21 17:18:35
【问题描述】:

我正在努力学习 W. Chun 的 Python 核心应用程序编程练习:

2-6。日间服务。使用 socket.getservbyname() 来确定 UDP 协议下“白天”服务的端口号。检查 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()

提前感谢您的宝贵时间

【问题讨论】:

    标签: python python-2.7 network-programming udp


    【解决方案1】:

    我认为您的代码完全有效,但没有 UDP 服务 在 time.nist.gov.

    如果您先使用 udpCliSock.connect(ADDR),然后再使用 send() sendto(),你会得到一个connection refused 错误。这通常 表示没有人在听。

    如果使用 sendto(),则会抑制此错误(无连接 UDP...)。

    我针对我自己的 cpp-lib (https://github.com/gewesp/cpp-lib) 中的 UDP 类测试了您的代码,并且 只要服务器实际回复,它就可以正常工作。

    NIST 说:

    1. 还强烈建议在 tcp 端口 13 上使用 NIST“DAYTIME”协议的用户升级到网络时间协议,该协议可提供更高的准确性并需要更少的网络带宽。 NIST 时间客户端 (nistime-32bit.exe) 支持这两种协议。我们预计在 2013 年底前用基于 udp 的版本替换此协议的 tcp 版本。

    我读到了,因为他们目前正在运行 TCPonly,并将尽快切换到 UDP 当他们开始处理它时。

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

    【讨论】:

    • 错误不是“抑制”:只是它不能被路由到套接字,因为操作系统不知道是哪个套接字引起的,除非有一个连接到源导致它的 ICMP 消息。
    【解决方案2】:

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

    Service Port Protocol Reference
    Daytime service 13 TCP and UDP [1]
    Time service 37 TCP and UDP [2]
    Network Time Protocol (NTP) 123 UDP [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 位无符号整数。您可以将 1900 年 1 月 1 日的相对时间(以秒为单位)转换为日期时间对象。

    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
    

    【讨论】:

      猜你喜欢
      • 2015-06-21
      • 2014-01-09
      • 2018-10-07
      • 2012-01-06
      • 2016-02-16
      • 2021-02-03
      • 2020-06-22
      • 2012-01-04
      • 1970-01-01
      相关资源
      最近更新 更多