簡體   English   中英

UDP 日間服務客戶端沒有響應

[英]UDP Daytime service client getting no response

我正在努力學習 W. Chun 的 Python Core Application Programming 中的以下練習:

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()

提前感謝您的時間

我認為您的代碼完全有效,但 time.nist.gov 上沒有 UDP 服務。

如果您先使用 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 版本。

我讀到了這一點,因為他們目前運行 TCP,一旦他們開始使用它就會切換到 UDP。

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

有 3 個“時間”協議服務,每個服務在不同的端口上運行:

服務 港口 協議 參考
日間服務 13 TCP 和 UDP [1]
時間服務 37 TCP 和 UDP [2]
網絡時間協議 (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 位無符號整數。 您可以將 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM