ΠΠ΄ΡΠ°Π²ΡΡΠ²ΡΠΉΡΠ΅, Ρ
Π°Π±ΡΠ°ΡΠ·Π΅ΡΡ. Π‘Π΅Π³ΠΎΠ΄Π½Ρ Ρ Ρ
ΠΎΡΡ ΡΠ°ΡΡΠΊΠ°Π·Π°ΡΡ ΠΎ ΡΠΎΠΌ, ΠΊΠ°ΠΊ Π½Π°ΠΏΠΈΡΠ°ΡΡ ΡΠ²ΠΎΠΉ ΠΏΡΠΎΡΡΠ΅Π½ΡΠΊΠΈΠΉ NTP ΠΊΠ»ΠΈΠ΅Π½Ρ. Π ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΌ, ΡΠ°Π·Π³ΠΎΠ²ΠΎΡ Π·Π°ΠΉΠ΄Π΅Ρ ΠΎ ΡΡΡΡΠΊΡΡΡΠ΅ ΠΏΠ°ΠΊΠ΅ΡΠ° ΠΈ ΡΠΏΠΎΡΠΎΠ±Π΅ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ ΠΎΡΠ²Π΅ΡΠ° Ρ NTP ΡΠ΅ΡΠ²Π΅ΡΠ°. ΠΠΎΠ΄ Π±ΡΠ΄Π΅Ρ Π½Π°ΠΏΠΈΡΠ°Π½ Π½Π° ΠΏΠΈΡΠΎΠ½Π΅, ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ, ΠΊΠ°ΠΊ ΠΌΠ½Π΅ ΠΊΠ°ΠΆΠ΅ΡΡΡ, Π»ΡΡΡΠ΅Π³ΠΎ ΡΠ·ΡΠΊΠ° Π΄Π»Ρ ΠΏΠΎΠ΄ΠΎΠ±Π½ΡΡ
Π²Π΅ΡΠ΅ΠΉ ΠΏΡΠΎΡΡΠΎ Π½Π΅ Π½Π°ΠΉΡΠΈ. ΠΠ½Π°ΡΠΎΠΊΠΈ ΠΎΠ±ΡΠ°ΡΡΡ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° ΡΡ
ΠΎΠΆΠ΅ΡΡΡ ΠΊΠΎΠ΄Π° Ρ ΠΊΠΎΠ΄ΠΎΠΌ ntplib β Ρ Β«Π²Π΄ΠΎΡ
Π½ΠΎΠ²Π»ΡΠ»ΡΡΒ» ΠΈΠΌΠ΅Π½Π½ΠΎ ΠΈΠΌ.
ΠΡΠ°ΠΊ, ΡΡΠΎ Π²ΠΎΠΎΠ±ΡΠ΅ ΡΠ°ΠΊΠΎΠ΅ NTP? NTP β ΠΏΡΠΎΡΠΎΠΊΠΎΠ» Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΡ Ρ ΡΠ΅ΡΠ²Π΅ΡΠ°ΠΌΠΈ ΡΠΎΡΠ½ΠΎΠ³ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ. ΠΡΠΎΡ ΠΏΡΠΎΡΠΎΠΊΠΎΠ» ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π²ΠΎ ΠΌΠ½ΠΎΠ³ΠΈΡ
ΡΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ
ΠΌΠ°ΡΠΈΠ½Π°Ρ
. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, ΡΠ»ΡΠΆΠ±Π° w32tm Π² windows.
ΠΡΠ΅Π³ΠΎ ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ 5 Π²Π΅ΡΡΠΈΠΉ NTP ΠΏΡΠΎΡΠΎΠΊΠΎΠ»Π°. ΠΠ΅ΡΠ²Π°Ρ, 0-Ρ Π²Π΅ΡΡΠΈΡ (1985 Π³, RFC958)), Π² Π΄Π°Π½Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ ΡΡΠΈΡΠ°Π΅ΡΡΡ ΡΡΡΠ°ΡΠ΅Π²ΡΠ΅ΠΉ. Π‘Π΅ΠΉΡΠ°Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΡΡ Π±ΠΎΠ»Π΅Π΅ Π½ΠΎΠ²ΡΠ΅, 1-Ρ (1988, RFC1059), 2-Ρ(1989, RFC1119), 3-Ρ(1992, RFC1305) ΠΈ 4-Ρ(1996, RFC2030). 1-4 Π²Π΅ΡΡΠΈΠΈ ΡΠ²Π»ΡΡΡΡΡ ΡΠΎΠ²ΠΌΠ΅ΡΡΠΈΠΌΡΠΌΠΈ Π΄ΡΡΠ³ Ρ Π΄ΡΡΠ³ΠΎΠΌ, ΠΎΠ½ΠΈ ΠΎΡΠ»ΠΈΡΠ°ΡΡΡΡ Π»ΠΈΡΡ Π°Π»Π³ΠΎΡΠΈΡΠΌΠ°ΠΌΠΈ ΡΠ°Π±ΠΎΡΡ ΡΠ΅ΡΠ²Π΅ΡΠΎΠ².
Π€ΠΎΡΠΌΠ°Ρ ΠΏΠ°ΠΊΠ΅ΡΠ°
Leap indicator (ΠΈΠ½Π΄ΠΈΠΊΠ°ΡΠΎΡ ΠΊΠΎΡΡΠ΅ΠΊΡΠΈΠΈ) β ΡΠΈΡΠ»ΠΎ, ΠΏΠΎΠΊΠ°Π·ΡΠ²Π°ΡΡΠ΅Π΅ ΠΏΡΠ΅Π΄ΡΠΏΡΠ΅ΠΆΠ΄Π΅Π½ΠΈΠ΅ ΠΎ ΡΠ΅ΠΊΡΠ½Π΄Π΅ ΠΊΠΎΠΎΡΠ΄ΠΈΠ½Π°ΡΠΈΠΈ. ΠΠ½Π°ΡΠ΅Π½ΠΈΠ΅:
- 0 β Π½Π΅Ρ ΠΊΠΎΡΡΠ΅ΠΊΡΠΈΠΈ
- 1 β ΠΏΠΎΡΠ»Π΅Π΄Π½ΡΡ ΠΌΠΈΠ½ΡΡΠ° Π΄Π½Ρ ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ 61 ΡΠ΅ΠΊΡΠ½Π΄Ρ
- 2 β ΠΏΠΎΡΠ»Π΅Π΄Π½ΡΡ ΠΌΠΈΠ½ΡΡΠ° Π΄Π½Ρ ΡΠΎΠ΄Π΅ΡΠΆΠΈΡ 59 ΡΠ΅ΠΊΡΠ½Π΄
- 3 β Π½Π΅ΠΈΡΠΏΡΠ°Π²Π½ΠΎΡΡΡ ΡΠ΅ΡΠ²Π΅ΡΠ° (Π²ΡΠ΅ΠΌΡ Π½Π΅ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·ΠΈΡΠΎΠ²Π°Π½ΠΎ)
Version number (Π½ΠΎΠΌΠ΅Ρ Π²Π΅ΡΡΠΈΠΈ) β Π½ΠΎΠΌΠ΅Ρ Π²Π΅ΡΡΠΈΠΈ ΠΏΡΠΎΡΠΎΠΊΠΎΠ»Π° NTP (1-4).
Mode (ΡΠ΅ΠΆΠΈΠΌ) β ΡΠ΅ΠΆΠΈΠΌ ΡΠ°Π±ΠΎΡΡ ΠΎΡΠΏΡΠ°Π²ΠΈΡΠ΅Π»Ρ ΠΏΠ°ΠΊΠ΅ΡΠ°. ΠΠ½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΎΡ 0 Π΄ΠΎ 7, Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΡΠ°ΡΡΡΠ΅:
- 3 β ΠΊΠ»ΠΈΠ΅Π½Ρ
- 4 β ΡΠ΅ΡΠ²Π΅Ρ
- 5 β ΡΠΈΡΠΎΠΊΠΎΠ²Π΅ΡΠ°ΡΠ΅Π»ΡΠ½ΡΠΉ ΡΠ΅ΠΆΠΈΠΌ
Stratum (ΡΡΠΎΠ²Π΅Π½Ρ Π½Π°ΡΠ»ΠΎΠ΅Π½ΠΈΡ) β ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΠΏΡΠΎΠΌΠ΅ΠΆΡΡΠΎΡΠ½ΡΡ
ΡΠ»ΠΎΠ΅Π² ΠΌΠ΅ΠΆΠ΄Ρ ΡΠ΅ΡΠ²Π΅ΡΠΎΠΌ ΠΈ ΡΡΠ°Π»ΠΎΠ½Π½ΡΠΌΠΈ ΡΠ°ΡΠ°ΠΌΠΈ (1 β ΡΠ΅ΡΠ²Π΅Ρ Π±Π΅ΡΠ΅Ρ Π΄Π°Π½Π½ΡΠ΅ Π½Π΅ΠΏΠΎΡΡΠ΅Π΄ΡΡΠ²Π΅Π½Π½ΠΎ Ρ ΡΡΠ°Π»ΠΎΠ½Π½ΡΡ
ΡΠ°ΡΠΎΠ², 2 β ΡΠ΅ΡΠ²Π΅Ρ Π±Π΅ΡΠ΅Ρ Π΄Π°Π½Π½ΡΠ΅ Ρ ΡΠ΅ΡΠ²Π΅ΡΠ° Ρ ΡΡΠΎΠ²Π½Π΅ΠΌ 1 ΠΈ Ρ.Π΄.).
Pool β ΡΠ΅Π»ΠΎΠ΅ ΡΠΈΡΠ»ΠΎ ΡΠΎ Π·Π½Π°ΠΊΠΎΠΌ, ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΡΡΠ΅Π΅ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»ΡΠ½ΡΠΉ ΠΈΠ½ΡΠ΅ΡΠ²Π°Π» ΠΌΠ΅ΠΆΠ΄Ρ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΡΠΌΠΈ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡΠΌΠΈ. NTP-ΠΊΠ»ΠΈΠ΅Π½Ρ ΡΠΊΠ°Π·ΡΠ²Π°Π΅Ρ Π·Π΄Π΅ΡΡ ΠΈΠ½ΡΠ΅ΡΠ²Π°Π», Ρ ΠΊΠΎΡΠΎΡΡΠΌ ΠΎΠ½ ΠΏΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅Ρ ΠΎΠΏΡΠ°ΡΠΈΠ²Π°ΡΡ ΡΠ΅ΡΠ²Π΅Ρ, Π° NTP-ΡΠ΅ΡΠ²Π΅Ρ β ΠΈΠ½ΡΠ΅ΡΠ²Π°Π», Ρ ΠΊΠΎΡΠΎΡΡΠΌ ΠΎΠ½ ΠΏΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅Ρ, ΡΡΠΎΠ±Ρ Π΅Π³ΠΎ ΠΎΠΏΡΠ°ΡΠΈΠ²Π°Π»ΠΈ. ΠΠ½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΠ°Π²Π½ΠΎ Π΄Π²ΠΎΠΈΡΠ½ΠΎΠΌΡ Π»ΠΎΠ³Π°ΡΠΈΡΠΌΡ ΡΠ΅ΠΊΡΠ½Π΄.
Precision (ΡΠΎΡΠ½ΠΎΡΡΡ) β ΡΠ΅Π»ΠΎΠ΅ ΡΠΈΡΠ»ΠΎ ΡΠΎ Π·Π½Π°ΠΊΠΎΠΌ, ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΡΡΠ΅Π΅ ΡΠΎΡΠ½ΠΎΡΡΡ ΡΠΈΡΡΠ΅ΠΌΠ½ΡΡ
ΡΠ°ΡΠΎΠ². ΠΠ½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΠ°Π²Π½ΠΎ Π΄Π²ΠΎΠΈΡΠ½ΠΎΠΌΡ Π»ΠΎΠ³Π°ΡΠΈΡΠΌΡ ΡΠ΅ΠΊΡΠ½Π΄.
Root delay (Π·Π°Π΄Π΅ΡΠΆΠΊΠ° ΡΠ΅ΡΠ²Π΅ΡΠ°) β Π²ΡΠ΅ΠΌΡ, Π·Π° ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΈΡ ΡΠ°ΡΠΎΠ² Π΄ΠΎΡ
ΠΎΠ΄ΡΡ Π΄ΠΎ NTP-ΡΠ΅ΡΠ²Π΅ΡΠ°, ΠΊΠ°ΠΊ ΡΠΈΡΠ»ΠΎ ΡΠ΅ΠΊΡΠ½Π΄ Ρ ΡΠΈΠΊΡΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠΉ ΡΠΎΡΠΊΠΎΠΉ.
Root dispersion (ΡΠ°Π·Π±ΡΠΎΡ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΈΠΉ ΡΠ΅ΡΠ²Π΅ΡΠ°) β ΡΠ°Π·Π±ΡΠΎΡ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΈΠΉ ΡΠ°ΡΠΎΠ² NTP-ΡΠ΅ΡΠ²Π΅ΡΠ° ΠΊΠ°ΠΊ ΡΠΈΡΠ»ΠΎ ΡΠ΅ΠΊΡΠ½Π΄ Ρ ΡΠΈΠΊΡΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠΉ ΡΠΎΡΠΊΠΎΠΉ.
Ref id (ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ ΠΈΡΡΠΎΡΠ½ΠΈΠΊΠ°) β id ΡΠ°ΡΠΎΠ². ΠΡΠ»ΠΈ ΡΠ΅ΡΠ²Π΅Ρ ΠΈΠΌΠ΅Π΅Ρ ΡΡΡΠ°ΡΡΠΌ 1, ΡΠΎ ref id β Π½Π°Π·Π²Π°Π½ΠΈΠ΅ Π°ΡΠΎΠΌΠ½ΡΡ
ΡΠ°ΡΠΎΠ² (4 ASCII ΡΠΈΠΌΠ²ΠΎΠ»Π°). ΠΡΠ»ΠΈ ΡΠ΅ΡΠ²Π΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ Π΄ΡΡΠ³ΠΎΠΉ ΡΠ΅ΡΠ²Π΅Ρ, ΡΠΎ Π² ref id Π·Π°ΠΏΠΈΡΠ°Π½ Π°Π΄ΡΠ΅Ρ ΡΡΠΎΠ³ΠΎ ΡΠ΅ΡΠ²Π΅ΡΠ°.
ΠΠΎΡΠ»Π΅Π΄Π½ΠΈΠ΅ 4 ΠΏΠΎΠ»Ρ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΡΡ ΠΈΠ· ΡΠ΅Π±Ρ Π²ΡΠ΅ΠΌΡ β 32 Π±ΠΈΡΠ° β ΡΠ΅Π»Π°Ρ ΡΠ°ΡΡΡ, 32 Π±ΠΈΡΠ° β Π΄ΡΠΎΠ±Π½Π°Ρ ΡΠ°ΡΡΡ.
Reference β ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΠ΅ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΈΡ ΡΠ°ΡΠΎΠ² Π½Π° ΡΠ΅ΡΠ²Π΅ΡΠ΅.
Originate β Π²ΡΠ΅ΠΌΡ, ΠΊΠΎΠ³Π΄Π° ΠΏΠ°ΠΊΠ΅Ρ Π±ΡΠ» ΠΎΡΠΏΡΠ°Π²Π»Π΅Π½ (Π·Π°ΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ ΡΠ΅ΡΠ²Π΅ΡΠΎΠΌ β ΠΎΠ± ΡΡΠΎΠΌ Π½ΠΈΠΆΠ΅).
Receive β Π²ΡΠ΅ΠΌΡ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΠΏΠ°ΠΊΠ΅ΡΠ° ΡΠ΅ΡΠ²Π΅ΡΠΎΠΌ.
Transmit β Π²ΡΠ΅ΠΌΡ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ ΠΏΠ°ΠΊΠ΅ΡΠ° Ρ ΡΠ΅ΡΠ²Π΅ΡΠ° ΠΊΠ»ΠΈΠ΅Π½ΡΡ (Π·Π°ΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ ΠΊΠ»ΠΈΠ΅Π½ΡΠΎΠΌ, ΠΎΠ± ΡΡΠΎΠΌ ΡΠΎΠΆΠ΅ Π½ΠΈΠΆΠ΅).
ΠΠ²Π° ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΡ ΠΏΠΎΠ»Ρ ΡΠ°ΡΡΠΌΠ°ΡΡΠΈΠ²Π°ΡΡ Π½Π΅ Π±ΡΠ΄Π΅ΠΌ.
ΠΠ°ΠΏΠΈΡΠ΅ΠΌ Π½Π°Ρ ΠΏΠ°ΠΊΠ΅Ρ:
ΠΠΎΠ΄ ΠΏΠ°ΠΊΠ΅ΡΠ°
class NTPPacket:
_FORMAT = "!B B b b 11I"
def __init__(self, version_number=2, mode=3, transmit=0):
# Necessary of enter leap second (2 bits)
self.leap_indicator = 0
# Version of protocol (3 bits)
self.version_number = version_number
# Mode of sender (3 bits)
self.mode = mode
# The level of "layering" reading time (1 byte)
self.stratum = 0
# Interval between requests (1 byte)
self.pool = 0
# Precision (log2) (1 byte)
self.precision = 0
# Interval for the clock reach NTP server (4 bytes)
self.root_delay = 0
# Scatter the clock NTP-server (4 bytes)
self.root_dispersion = 0
# Indicator of clocks (4 bytes)
self.ref_id = 0
# Last update time on server (8 bytes)
self.reference = 0
# Time of sending packet from local machine (8 bytes)
self.originate = 0
# Time of receipt on server (8 bytes)
self.receive = 0
# Time of sending answer from server (8 bytes)
self.transmit = transmit
Π§ΡΠΎΠ±Ρ ΡΠ»Π°ΡΡ (ΠΈ ΠΏΡΠΈΠ½ΠΈΠΌΠ°ΡΡ) ΠΏΠ°ΠΊΠ΅Ρ Π½Π° ΡΠ΅ΡΠ²Π΅Ρ, ΠΌΡ Π΄ΠΎΠ»ΠΆΠ½Ρ ΡΠΌΠ΅ΡΡ ΠΏΡΠ΅Π²ΡΠ°ΡΠ°ΡΡ Π΅Π³ΠΎ Π² ΠΌΠ°ΡΡΠΈΠ² Π±Π°ΠΉΡ.
ΠΠ»Ρ ΡΡΠΎΠΉ (ΠΈ ΠΎΠ±ΡΠ°ΡΠ½ΠΎΠΉ) ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ Π½Π°ΠΏΠΈΡΠ΅ΠΌ Π΄Π²Π΅ ΡΡΠ½ΠΊΡΠΈΠΈ β pack() ΠΈ unpack():
Π€ΡΠ½ΠΊΡΠΈΡ pack
def pack(self):
return struct.pack(NTPPacket._FORMAT,
(self.leap_indicator << 6) +
(self.version_number << 3) + self.mode,
self.stratum,
self.pool,
self.precision,
int(self.root_delay) + get_fraction(self.root_delay, 16),
int(self.root_dispersion) +
get_fraction(self.root_dispersion, 16),
self.ref_id,
int(self.reference),
get_fraction(self.reference, 32),
int(self.originate),
get_fraction(self.originate, 32),
int(self.receive),
get_fraction(self.receive, 32),
int(self.transmit),
get_fraction(self.transmit, 32))
Π€ΡΠ½ΠΊΡΠΈΡ unpack
def unpack(self, data: bytes):
unpacked_data = struct.unpack(NTPPacket._FORMAT, data)
self.leap_indicator = unpacked_data[0] >> 6 # 2 bits
self.version_number = unpacked_data[0] >> 3 & 0b111 # 3 bits
self.mode = unpacked_data[0] & 0b111 # 3 bits
self.stratum = unpacked_data[1] # 1 byte
self.pool = unpacked_data[2] # 1 byte
self.precision = unpacked_data[3] # 1 byte
# 2 bytes | 2 bytes
self.root_delay = (unpacked_data[4] >> 16) +
(unpacked_data[4] & 0xFFFF) / 2 ** 16
# 2 bytes | 2 bytes
self.root_dispersion = (unpacked_data[5] >> 16) +
(unpacked_data[5] & 0xFFFF) / 2 ** 16
# 4 bytes
self.ref_id = str((unpacked_data[6] >> 24) & 0xFF) + " " +
str((unpacked_data[6] >> 16) & 0xFF) + " " +
str((unpacked_data[6] >> 8) & 0xFF) + " " +
str(unpacked_data[6] & 0xFF)
self.reference = unpacked_data[7] + unpacked_data[8] / 2 ** 32 # 8 bytes
self.originate = unpacked_data[9] + unpacked_data[10] / 2 ** 32 # 8 bytes
self.receive = unpacked_data[11] + unpacked_data[12] / 2 ** 32 # 8 bytes
self.transmit = unpacked_data[13] + unpacked_data[14] / 2 ** 32 # 8 bytes
return self
ΠΠ»Ρ Π»Π΅Π½ΡΡΠ΅Π², Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ β ΠΊΠΎΠ΄, ΠΏΡΠ΅Π²ΡΠ°ΡΠ°ΡΡΠΈΠΉ ΠΏΠ°ΠΊΠ΅Ρ Π² ΠΊΡΠ°ΡΠΈΠ²ΡΡ ΡΡΡΠΎΠΊΡ
def to_display(self):
return "Leap indicator: {0.leap_indicator}n"
"Version number: {0.version_number}n"
"Mode: {0.mode}n"
"Stratum: {0.stratum}n"
"Pool: {0.pool}n"
"Precision: {0.precision}n"
"Root delay: {0.root_delay}n"
"Root dispersion: {0.root_dispersion}n"
"Ref id: {0.ref_id}n"
"Reference: {0.reference}n"
"Originate: {0.originate}n"
"Receive: {0.receive}n"
"Transmit: {0.transmit}"
.format(self)
ΠΡΠΏΡΠ°Π²ΠΊΠ° ΠΏΠ°ΠΊΠ΅ΡΠ° Π½Π° ΡΠ΅ΡΠ²Π΅Ρ
ΠΠ° ΡΠ΅ΡΠ²Π΅Ρ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΠΎΡΠΏΡΠ°Π²ΠΈΡΡ ΠΏΠ°ΠΊΠ΅Ρ Ρ Π·Π°ΠΏΠΎΠ»Π½Π΅Π½Π½ΡΠΌΠΈ ΠΏΠΎΠ»ΡΠΌΠΈ Version, Mode ΠΈ Transmit. Π Transmit Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΡΠΊΠ°Π·Π°ΡΡ ΡΠ΅ΠΊΡΡΠ΅Π΅ Π²ΡΠ΅ΠΌΡ Π½Π° Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎΠΉ ΠΌΠ°ΡΠΈΠ½Π΅ (ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΡΠ΅ΠΊΡΠ½Π΄ Ρ 1 ΡΠ½Π²Π°ΡΡ 1900 Π³), Π²Π΅ΡΡΠΈΡ β Π»ΡΠ±Π°Ρ ΠΈΠ· 1-4, ΡΠ΅ΠΆΠΈΠΌ β 3 (ΡΠ΅ΠΈΠΆΠΌ ΠΊΠ»ΠΈΠ΅Π½ΡΠ°).
Π‘Π΅ΡΠ²Π΅Ρ, ΠΏΡΠΈΠ½ΡΠ² Π·Π°ΠΏΡΠΎΡ, Π·Π°ΠΏΠΎΠ»Π½ΡΠ΅Ρ Π² NTP-ΠΏΠ°ΠΊΠ΅ΡΠ΅ Π²ΡΠ΅ ΠΏΠΎΠ»Ρ, ΡΠΊΠΎΠΏΠΈΡΠΎΠ²Π°Π² Π² ΠΏΠΎΠ»Π΅ Originate Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΈΠ· Transmit, ΠΏΡΠΈΡΠ΅Π΄ΡΠ΅Π΅ Π² Π·Π°ΠΏΡΠΎΡΠ΅. ΠΠ»Ρ ΠΌΠ΅Π½Ρ ΡΠ²Π»ΡΠ΅ΡΡΡ Π·Π°Π³Π°Π΄ΠΊΠΎΠΉ, ΠΏΠΎΡΠ΅ΠΌΡ ΠΊΠ»ΠΈΠ΅Π½Ρ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ ΡΡΠ°Π·Ρ Π·Π°ΠΏΠΎΠ»Π½ΠΈΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΡΠ²ΠΎΠ΅Π³ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ Π² ΠΏΠΎΠ»Π΅ Originate. Π ΠΈΡΠΎΠ³Π΅, ΠΊΠΎΠ³Π΄Π° ΠΏΠ°ΠΊΠ΅Ρ ΠΏΡΠΈΡ ΠΎΠ΄ΠΈΡ ΠΎΠ±ΡΠ°ΡΠ½ΠΎ, Ρ ΠΊΠ»ΠΈΠ΅Π½ΡΠ° Π΅ΡΡΡ 4 Π·Π½Π°ΡΠ΅Π½ΠΈΡ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ β Π²ΡΠ΅ΠΌΡ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ Π·Π°ΠΏΡΠΎΡΠ° (Originate), Π²ΡΠ΅ΠΌΡ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ Π·Π°ΠΏΡΠΎΡΠ° ΡΠ΅ΡΠ²Π΅ΡΠΎΠΌ (Receive), Π²ΡΠ΅ΠΌΡ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ ΠΎΡΠ²Π΅ΡΠ° ΡΠ΅ΡΠ²Π΅ΡΠΎΠΌ (Transmit) ΠΈ Π²ΡΠ΅ΠΌΡ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΠΎΡΠ²Π΅ΡΠ° ΠΊΠ»ΠΈΠ΅Π½ΡΠΎΠΌ β Arrive (Π½Π΅Ρ Π² ΠΏΠ°ΠΊΠ΅ΡΠ΅). Π‘ ΠΏΠΎΠΌΠΎΡΡΡ ΡΡΠΈΡ Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎΠ΅ Π²ΡΠ΅ΠΌΡ.
ΠΠΎΠ΄ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ ΠΈ ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΠΏΠ°ΠΊΠ΅ΡΠ°
# Time difference between 1970 and 1900, seconds
FORMAT_DIFF = (datetime.date(1970, 1, 1) - datetime.date(1900, 1, 1)).days * 24 * 3600
# Waiting time for recv (seconds)
WAITING_TIME = 5
server = "pool.ntp.org"
port = 123
packet = NTPPacket(version_number=2, mode=3, transmit=time.time() + FORMAT_DIFF)
answer = NTPPacket()
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
s.settimeout(WAITING_TIME)
s.sendto(packet.pack(), (server, port))
data = s.recv(48)
arrive_time = time.time() + FORMAT_DIFF
answer.unpack(data)
ΠΠ±ΡΠ°Π±ΠΎΡΠΊΠ° Π΄Π°Π½Π½ΡΡ Ρ ΡΠ΅ΡΠ²Π΅ΡΠ°
ΠΠ±ΡΠ°Π±ΠΎΡΠΊΠ° Π΄Π°Π½Π½ΡΡ Ρ ΡΠ΅ΡΠ²Π΅ΡΠ° Π°Π½Π°Π»ΠΎΠ³ΠΈΡΠ½Π° Π΄Π΅ΠΉΡΡΠ²ΠΈΡΠΌ Π°Π½Π³Π»ΠΈΠΉΡΠΊΠΎΠ³ΠΎ Π΄ΠΆΠ΅Π½ΡΠ»ΡΠΌΠ΅Π½Π° ΠΈΠ· ΡΡΠ°ΡΠΎΠΉ Π·Π°Π΄Π°ΡΠΈ Π ΡΠΉΠΌΠΎΠ½Π΄Π° Π. Π‘ΠΌΠ°Π»Π»ΠΈΠ°Π½Π° (1978): Β«Π£ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΡΠ΅Π»ΠΎΠ²Π΅ΠΊΠ° Π½Π΅ Π±ΡΠ»ΠΎ Π½Π°ΡΡΡΠ½ΡΡ ΡΠ°ΡΠΎΠ², Π½ΠΎ Π·Π°ΡΠΎ Π΄ΠΎΠΌΠ° Π²ΠΈΡΠ΅Π»ΠΈ ΡΠΎΡΠ½ΡΠ΅ Π½Π°ΡΡΠ΅Π½Π½ΡΠ΅ ΡΠ°ΡΡ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΎΠ½ ΠΈΠ½ΠΎΠ³Π΄Π° Π·Π°Π±ΡΠ²Π°Π» Π·Π°Π²ΠΎΠ΄ΠΈΡΡ. ΠΠ΄Π½Π°ΠΆΠ΄Ρ, Π·Π°Π±ΡΠ² ΠΎΡΠ΅ΡΠ΅Π΄Π½ΠΎΠΉ ΡΠ°Π· Π·Π°Π²Π΅ΡΡΠΈ ΡΠ°ΡΡ, ΠΎΠ½ ΠΎΡΠΏΡΠ°Π²ΠΈΠ»ΡΡ Π² Π³ΠΎΡΡΠΈ ΠΊ ΡΠ²ΠΎΠ΅ΠΌΡ Π΄ΡΡΠ³Ρ, ΠΏΡΠΎΠ²Π΅Π» Ρ ΡΠΎΠ³ΠΎ Π²Π΅ΡΠ΅Ρ, Π° Π²Π΅ΡΠ½ΡΠ²ΡΠΈΡΡ Π΄ΠΎΠΌΠΎΠΉ, ΡΡΠΌΠ΅Π» ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎ ΠΏΠΎΡΡΠ°Π²ΠΈΡΡ ΡΠ°ΡΡ. ΠΠ°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ Π΅ΠΌΡ ΡΠ΄Π°Π»ΠΎΡΡ ΡΡΠΎ ΡΠ΄Π΅Π»Π°ΡΡ, Π΅ΡΠ»ΠΈ Π²ΡΠ΅ΠΌΡ Π² ΠΏΡΡΠΈ Π·Π°ΡΠ°Π½Π΅Π΅ ΠΈΠ·Π²Π΅ΡΡΠ½ΠΎ Π½Π΅ Π±ΡΠ»ΠΎ?Β» ΠΡΠ²Π΅Ρ ΡΠ°ΠΊΠΎΠ²: Β«ΠΡΡ ΠΎΠ΄Ρ ΠΈΠ· Π΄ΠΎΠΌΠ°, ΡΠ΅Π»ΠΎΠ²Π΅ΠΊ Π·Π°Π²ΠΎΠ΄ΠΈΡ ΡΠ°ΡΡ ΠΈ Π·Π°ΠΏΠΎΠΌΠΈΠ½Π°Π΅Ρ, Π² ΠΊΠ°ΠΊΠΎΠΌ ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ Π½Π°Ρ ΠΎΠ΄ΡΡΡΡ ΡΡΡΠ΅Π»ΠΊΠΈ. ΠΡΠΈΠ΄Ρ ΠΊ Π΄ΡΡΠ³Ρ ΠΈ ΡΡ ΠΎΠ΄Ρ ΠΈΠ· Π³ΠΎΡΡΠ΅ΠΉ, ΠΎΠ½ ΠΎΡΠΌΠ΅ΡΠ°Π΅Ρ Π²ΡΠ΅ΠΌΡ ΡΠ²ΠΎΠ΅Π³ΠΎ ΠΏΡΠΈΡ ΠΎΠ΄Π° ΠΈ ΡΡ ΠΎΠ΄Π°. ΠΡΠΎ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π΅ΠΌΡ ΡΠ·Π½Π°ΡΡ, ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΎΠ½ Π½Π°Ρ ΠΎΠ΄ΠΈΠ»ΡΡ Π² Π³ΠΎΡΡΡΡ . ΠΠ΅ΡΠ½ΡΠ²ΡΠΈΡΡ Π΄ΠΎΠΌΠΎΠΉ ΠΈ Π²Π·Π³Π»ΡΠ½ΡΠ² Π½Π° ΡΠ°ΡΡ, ΡΠ΅Π»ΠΎΠ²Π΅ΠΊ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅Ρ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΡ ΡΠ²ΠΎΠ΅Π³ΠΎ ΠΎΡΡΡΡΡΡΠ²ΠΈΡ. ΠΡΡΠΈΡΠ°Ρ ΠΈΠ· ΡΡΠΎΠ³ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ ΡΠΎ Π²ΡΠ΅ΠΌΡ, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΎΠ½ ΠΏΡΠΎΠ²Π΅Π» Π² Π³ΠΎΡΡΡΡ , ΡΠ΅Π»ΠΎΠ²Π΅ΠΊ ΡΠ·Π½Π°Π΅Ρ Π²ΡΠ΅ΠΌΡ, Π·Π°ΡΡΠ°ΡΠ΅Π½Π½ΠΎΠ΅ Π½Π° Π΄ΠΎΡΠΎΠ³Ρ ΡΡΠ΄Π° ΠΈ ΠΎΠ±ΡΠ°ΡΠ½ΠΎ. ΠΡΠΈΠ±Π°Π²ΠΈΠ² ΠΊΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ Π²ΡΡ ΠΎΠ΄Π° ΠΈΠ· Π³ΠΎΡΡΠ΅ΠΉ ΠΏΠΎΠ»ΠΎΠ²ΠΈΠ½Ρ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ, Π·Π°ΡΡΠ°ΡΠ΅Π½Π½ΠΎΠ³ΠΎ Π½Π° Π΄ΠΎΡΠΎΠ³Ρ, ΠΎΠ½ ΠΏΠΎΠ»ΡΡΠ°Π΅Ρ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΡΠ·Π½Π°ΡΡ Π²ΡΠ΅ΠΌΡ ΠΏΡΠΈΡ ΠΎΠ΄Π° Π΄ΠΎΠΌΠΎΠΉ ΠΈ ΠΏΠ΅ΡΠ΅Π²Π΅ΡΡΠΈ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ ΡΡΡΠ΅Π»ΠΊΠΈ ΡΠ²ΠΎΠΈΡ ΡΠ°ΡΠΎΠ².Β»
ΠΠ°Ρ ΠΎΠ΄ΠΈΠΌ Π²ΡΠ΅ΠΌΡ ΡΠ°Π±ΠΎΡΡ ΡΠ΅ΡΠ²Π΅ΡΠ° Π½Π°Π΄ Π·Π°ΠΏΡΠΎΡΠΎΠΌ:
- ΠΠ°Ρ ΠΎΠ΄ΠΈΠΌ Π²ΡΠ΅ΠΌΡ ΠΏΡΡΠΈ ΠΏΠ°ΠΊΠ΅ΡΠ° ΠΎΡ ΠΊΠ»ΠΈΠ΅Π½ΡΠ° ΠΊ ΡΠ΅ΡΠ²Π΅ΡΡ: ((Arrive β Originate) β (Transmit β Receive)) / 2
- ΠΠ°Ρ
ΠΎΠ΄ΠΈΠΌ ΡΠ°Π·Π½ΠΈΡΡ ΠΌΠ΅ΠΆΠ΄Ρ Π²ΡΠ΅ΠΌΠ΅Π½Π΅ΠΌ ΠΊΠ»ΠΈΠ΅Π½ΡΠ° ΠΈ ΡΠ΅ΡΠ²Π΅ΡΠ°:
Receive β Originate β ((Arrive β Originate) β (Transmit β Receive)) / 2 =
2 * Receive β 2 * Originate β Arrive + Originate + Transmit β Receive =
Receive β Originate β Arrive + Transmit
ΠΠΎΠ±Π°Π²Π»ΡΠ΅ΠΌ ΠΏΠΎΠ»ΡΡΠ΅Π½Π½ΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ ΠΊ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎΠΌΡ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ ΠΈ ΡΠ°Π΄ΡΠ΅ΠΌΡΡ ΠΆΠΈΠ·Π½ΠΈ.
ΠΡΠ²ΠΎΠ΄ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ°
time_different = answer.get_time_different(arrive_time)
result = "Time difference: {}nServer time: {}n{}".format(
time_different,
datetime.datetime.fromtimestamp(time.time() + time_different).strftime("%c"),
answer.to_display())
print(result)
ΠΠΎΠ»Π΅Π·Π½Π°Ρ
ΠΡΡΠΎΡΠ½ΠΈΠΊ: habr.com