Kaabo, Habrausers. Loni Mo fẹ lati sọrọ nipa bi o ṣe le kọ alabara NTP ti o rọrun tirẹ. Ni ipilẹ, ibaraẹnisọrọ naa yoo yipada si ọna ti apo-iwe ati ọna ti sisẹ esi lati ọdọ olupin NTP. Awọn koodu yoo wa ni kikọ ni Python, nitori o dabi si mi wipe o wa ni nìkan ko si dara ede fun iru ohun. Connoisseurs yoo ṣe akiyesi ibajọra ti koodu naa pẹlu koodu ntplib - Mo jẹ “atilẹyin” nipasẹ rẹ.
Nitorina kini gangan jẹ NTP? NTP jẹ ilana fun ibaraenisepo pẹlu awọn olupin akoko gangan. Ilana yii lo ni ọpọlọpọ awọn ẹrọ igbalode. Fun apẹẹrẹ, iṣẹ w32tm ni awọn window.
Àròpọ̀ àwọn ẹ̀yà márùn-ún ló wà nínú ìlànà NTP. Ẹ̀yà àkọ́kọ́, ẹ̀yà 0 (1985, RFC958), ni a kà sí pé ó ti gbó. Àwọn ẹ̀yà tuntun ló ń lò lọ́wọ́lọ́wọ́: ẹ̀yà 1 (1988, RFC1059), ẹ̀yà 2 (1989, RFC1119), ẹ̀yà 3 (1992, RFC1305), àti ẹ̀yà 4 (1996, RFC2030). Àwọn ẹ̀yà 1-4 bá ara wọn mu; wọ́n yàtọ̀ síra nínú àwọn algoridimu ìṣiṣẹ́ wọn nìkan. apèsè.
Package kika

Atọka fifo (Atọka atunṣe) - nọmba kan ti o nfihan ikilọ nipa iṣẹju-aaya. Itumo:
- 0 - ko si atunṣe
- 1 - iṣẹju to kẹhin ti ọjọ ni awọn iṣẹju-aaya 61
- 2 - iṣẹju to kẹhin ti ọjọ ni awọn iṣẹju-aaya 59
- 3 – Aṣiṣe olupin (akoko ko ṣiṣẹpọ)
Nomba ikede (nọmba ẹya) - NTP bèèrè version nọmba (1-4).
mode (ipo) - awọn ọna mode ti awọn soso Olu. Iye lati 0 si 7, wọpọ julọ:
- 3 – onibara
- 4 – olupin
- 5 – ipo igbohunsafefe
stratum (ipele ipele) - nọmba awọn ipele agbedemeji laarin olupin ati aago itọkasi (1 - olupin naa gba data taara lati aago itọkasi, 2 - olupin gba data lati ọdọ olupin pẹlu Layer 1, bbl).
pool jẹ odidi wole ti o nsoju aarin ti o pọju laarin awọn ifiranṣẹ itẹlera. Onibara NTP pato nihin ni aarin eyiti o nireti lati didi olupin naa, ati olupin NTP sọ asọye aarin eyiti o nireti lati di ibo. Iye naa jẹ dogba si logarithm alakomeji ti awọn aaya.
konge (ipeye) jẹ odidi ti o fowo si ti o nsoju deede aago eto. Iye naa jẹ dogba si logarithm alakomeji ti awọn aaya.
Gbongbo idaduro (Idaduro olupin) - akoko ti o gba fun awọn kika aago lati de ọdọ olupin NTP, gẹgẹbi nọmba aaye-aaya ti awọn aaya.
Gbongbo pipinka (itankale olupin) - itankale awọn kika aago olupin NTP bi nọmba awọn aaya pẹlu aaye ti o wa titi.
Ref id (Idamo orisun) - aago id. Ti olupin naa ba ni stratum 1, lẹhinna ref id ni orukọ aago atomiki (awọn ohun kikọ ASCII 4). Ti olupin naa ba lo olupin miiran, lẹhinna iwifun ref ni adirẹsi olupin yii ni.
Awọn aaye mẹrin ti o kẹhin jẹ aṣoju akoko - 4 bits - apakan odidi, 32 bits - apakan ida.
Reference - awọn kika aago tuntun lori olupin naa.
Ti ipilẹṣẹ - akoko ti apo ti firanṣẹ (ti o kun nipasẹ olupin - diẹ sii lori eyi ni isalẹ).
gba – akoko awọn soso ti a ti gba nipasẹ awọn olupin.
atagba - akoko ti fifiranṣẹ apo-iwe lati ọdọ olupin si alabara (ti o kun nipasẹ alabara, diẹ sii lori eyi ni isalẹ).
A kii yoo gbero awọn aaye meji ti o kẹhin.
Jẹ ki a kọ package wa:
Koodu idii
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
Lati firanṣẹ (ati gba) apo-iwe kan si olupin, a gbọdọ ni anfani lati yi pada sinu titobi baiti kan.
Fun iṣẹ yii (ati yiyipada), a yoo kọ awọn iṣẹ meji - idii () ati ṣiṣi silẹ ():
pack iṣẹ
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 iṣẹ
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
Fun awọn ọlẹ, bi ohun elo - koodu ti o yi package sinu okun ti o lẹwa
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)
Fifiranṣẹ package kan si olupin naa
Pakẹti pẹlu awọn aaye ti o kun gbọdọ wa ni fifiranṣẹ si olupin naa version, mode и atagba. awọn atagba o gbọdọ pato awọn ti isiyi akoko lori awọn agbegbe ẹrọ (awọn nọmba ti aaya lati January 1, 1900), version - eyikeyi ti 1-4, mode - 3 (onibara mode).
Olupin naa, ti o ti gba ibeere naa, kun gbogbo awọn aaye ninu apo NTP, didakọ sinu aaye naa Ti ipilẹṣẹ iye lati atagba, eyiti o wa ninu ibeere naa. O jẹ ohun ijinlẹ fun mi idi ti alabara ko le fọwọsi lẹsẹkẹsẹ ni iye akoko rẹ ni aaye Ti ipilẹṣẹ. Bi abajade, nigbati soso naa ba pada, alabara ni awọn iye akoko 4 - akoko ti a firanṣẹ ibeere naa (Ti ipilẹṣẹ), akoko ti olupin gba ibeere naa (gba), akoko ti olupin naa fi esi ranṣẹ (atagba) ati akoko ti alabara gba esi - Dide (kii ṣe ninu package). Lilo awọn iye wọnyi a le ṣeto akoko to pe.
Package fifiranṣẹ ati gbigba koodu
# 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)
Nṣiṣẹ data lati olupin
Ṣiṣẹda data lati ọdọ olupin naa jẹ iru awọn iṣe ti okunrin arakunrin Gẹẹsi lati inu iṣoro atijọ ti Raymond M. Smullyan (1978): “Ọkunrin kan ko ni aago ọwọ-ọwọ, ṣugbọn aago odi deede wa ni ile, eyiti o gbagbe nigba miiran. si afẹfẹ. Ni ọjọ kan, ti o gbagbe lati tun aago rẹ pada, o lọ lati ṣabẹwo si ọrẹ rẹ, lo irọlẹ pẹlu rẹ, ati nigbati o pada si ile, o ṣakoso lati ṣeto aago ni deede. Bawo ni o ṣe ṣakoso lati ṣe eyi ti akoko irin-ajo ko ba mọ tẹlẹ? Ìdáhùn rẹ̀ ni pé: “Tí ẹnì kan bá kúrò nílé, ó máa ń fi aago rẹ̀ ṣíwọ́, á sì rántí ibi tí ọwọ́ wà. Lehin ti o wa si ọrẹ kan ati ki o lọ kuro ni awọn alejo, o ṣe akiyesi akoko ti dide ati ilọkuro rẹ. Èyí á jẹ́ kó lè mọ bó ṣe gùn tó. Pada si ile ati wiwo aago, eniyan pinnu iye akoko isansa rẹ. Nipa yiyọkuro akoko ti o lo lati ṣabẹwo, eniyan yoo rii akoko ti o lo lati rin irin-ajo lọ sibẹ ati pada. Nípa fífi ìdajì àkókò tí ó lò ní ojú ọ̀nà sí àkókò tí ó fi àwọn àlejò sílẹ̀, ó ní àǹfààní láti wá àkókò àtiwá sílé kí ó sì tún ọwọ́ aago rẹ̀ ṣe ní ìbámu pẹ̀lú.”
Wa akoko ti olupin n ṣiṣẹ lori ibeere kan:
- Wa akoko irin-ajo ti apo-iwe lati ọdọ alabara si olupin naa: ((De – Originate) – (Transmit –Gba)) / 2
- Wa iyatọ laarin akoko alabara ati olupin:
Gba - Originate - ((De - Originate) - (Transmit - Gba)) / 2 =
2 * Gba – 2 * Oti – De + Otisilẹ + Gbigbe – Gba =
Gba – Oti – De + Gbigbe
A ṣafikun iye abajade si akoko agbegbe ati gbadun igbesi aye.
Abajade abajade
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)
Wulo .
orisun: www.habr.com
