ಸರಳವಾದ NTP ಕ್ಲೈಂಟ್ ಅನ್ನು ಬರೆಯುವುದು

ಹಲೋ, ಹಬ್ರೂಸರ್ಸ್. ಇಂದು ನಾನು ನಿಮ್ಮ ಸ್ವಂತ ಸರಳ NTP ಕ್ಲೈಂಟ್ ಅನ್ನು ಹೇಗೆ ಬರೆಯುವುದು ಎಂಬುದರ ಕುರಿತು ಮಾತನಾಡಲು ಬಯಸುತ್ತೇನೆ. ಮೂಲಭೂತವಾಗಿ, ಸಂಭಾಷಣೆಯು ಪ್ಯಾಕೆಟ್ನ ರಚನೆ ಮತ್ತು NTP ಸರ್ವರ್ನಿಂದ ಪ್ರತಿಕ್ರಿಯೆಯನ್ನು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸುವ ವಿಧಾನಕ್ಕೆ ತಿರುಗುತ್ತದೆ. ಕೋಡ್ ಅನ್ನು ಪೈಥಾನ್‌ನಲ್ಲಿ ಬರೆಯಲಾಗುತ್ತದೆ, ಏಕೆಂದರೆ ಅಂತಹ ವಿಷಯಗಳಿಗೆ ಉತ್ತಮ ಭಾಷೆ ಇಲ್ಲ ಎಂದು ನನಗೆ ತೋರುತ್ತದೆ. ntplib ಕೋಡ್‌ನೊಂದಿಗೆ ಕೋಡ್‌ನ ಹೋಲಿಕೆಯನ್ನು ಅಭಿಜ್ಞರು ಗಮನಿಸುತ್ತಾರೆ - ನಾನು ಅದರಿಂದ "ಸ್ಫೂರ್ತಿ ಪಡೆದಿದ್ದೇನೆ".

ಹಾಗಾದರೆ NTP ನಿಖರವಾಗಿ ಏನು? NTP ಎನ್ನುವುದು ನಿಖರವಾದ ಸಮಯ ಸರ್ವರ್‌ಗಳೊಂದಿಗೆ ಸಂವಹನಕ್ಕಾಗಿ ಪ್ರೋಟೋಕಾಲ್ ಆಗಿದೆ. ಈ ಪ್ರೋಟೋಕಾಲ್ ಅನ್ನು ಅನೇಕ ಆಧುನಿಕ ಯಂತ್ರಗಳಲ್ಲಿ ಬಳಸಲಾಗುತ್ತದೆ. ಉದಾಹರಣೆಗೆ, ವಿಂಡೋಸ್ನಲ್ಲಿ w32tm ಸೇವೆ.

ಒಟ್ಟು NTP ಪ್ರೋಟೋಕಾಲ್‌ನ 5 ಆವೃತ್ತಿಗಳಿವೆ. ಮೊದಲನೆಯ ಆವೃತ್ತಿ 0 (1985, RFC958)), ಪ್ರಸ್ತುತ ಬಳಕೆಯಲ್ಲಿಲ್ಲ ಎಂದು ಪರಿಗಣಿಸಲಾಗಿದೆ. ಈಗ ಹೊಸದನ್ನು ಬಳಸಲಾಗಿದೆ, 1ನೇ (1988, RFC1059), 2ನೇ (1989, RFC1119), 3ನೇ (1992, RFC1305) ಮತ್ತು 4ನೇ (1996, RFC2030). 1-4 ಆವೃತ್ತಿಗಳು ಪರಸ್ಪರ ಹೊಂದಿಕೊಳ್ಳುತ್ತವೆ; ಅವು ಸರ್ವರ್ ಕಾರ್ಯಾಚರಣೆಯ ಕ್ರಮಾವಳಿಗಳಲ್ಲಿ ಮಾತ್ರ ಭಿನ್ನವಾಗಿರುತ್ತವೆ.

ಪ್ಯಾಕೇಜ್ ಸ್ವರೂಪ

ಸರಳವಾದ NTP ಕ್ಲೈಂಟ್ ಅನ್ನು ಬರೆಯುವುದು

ಅಧಿಕ ಸೂಚಕ (ತಿದ್ದುಪಡಿ ಸೂಚಕ) - ಸಮನ್ವಯ ಎರಡನೇ ಬಗ್ಗೆ ಎಚ್ಚರಿಕೆಯನ್ನು ಸೂಚಿಸುವ ಸಂಖ್ಯೆ. ಅರ್ಥ:

  • 0 - ಯಾವುದೇ ತಿದ್ದುಪಡಿ ಇಲ್ಲ
  • 1 - ದಿನದ ಕೊನೆಯ ನಿಮಿಷವು 61 ಸೆಕೆಂಡುಗಳನ್ನು ಒಳಗೊಂಡಿದೆ
  • 2 - ದಿನದ ಕೊನೆಯ ನಿಮಿಷವು 59 ಸೆಕೆಂಡುಗಳನ್ನು ಒಳಗೊಂಡಿದೆ
  • 3 - ಸರ್ವರ್ ಅಸಮರ್ಪಕ ಕ್ರಿಯೆ (ಸಮಯವನ್ನು ಸಿಂಕ್ರೊನೈಸ್ ಮಾಡಲಾಗಿಲ್ಲ)

ಆವೃತ್ತಿ ಸಂಖ್ಯೆ (ಆವೃತ್ತಿ ಸಂಖ್ಯೆ) - NTP ಪ್ರೋಟೋಕಾಲ್ ಆವೃತ್ತಿ ಸಂಖ್ಯೆ (1-4).

ಕ್ರಮದಲ್ಲಿ (ಮೋಡ್) - ಪ್ಯಾಕೆಟ್ ಕಳುಹಿಸುವವರ ಆಪರೇಟಿಂಗ್ ಮೋಡ್. 0 ರಿಂದ 7 ರವರೆಗಿನ ಮೌಲ್ಯ, ಅತ್ಯಂತ ಸಾಮಾನ್ಯ:

  • 3 - ಕ್ಲೈಂಟ್
  • 4 - ಸರ್ವರ್
  • 5 - ಪ್ರಸಾರ ಮೋಡ್

ಸ್ಟ್ರಾಟಮ್ (ಲೇಯರಿಂಗ್ ಮಟ್ಟ) - ಸರ್ವರ್ ಮತ್ತು ಉಲ್ಲೇಖ ಗಡಿಯಾರದ ನಡುವಿನ ಮಧ್ಯಂತರ ಪದರಗಳ ಸಂಖ್ಯೆ (1 - ಸರ್ವರ್ ನೇರವಾಗಿ ಉಲ್ಲೇಖ ಗಡಿಯಾರದಿಂದ ಡೇಟಾವನ್ನು ತೆಗೆದುಕೊಳ್ಳುತ್ತದೆ, 2 - ಸರ್ವರ್ ಲೇಯರ್ 1, ಇತ್ಯಾದಿಗಳೊಂದಿಗೆ ಸರ್ವರ್‌ನಿಂದ ಡೇಟಾವನ್ನು ತೆಗೆದುಕೊಳ್ಳುತ್ತದೆ).
ಸಾಮಾನ್ಯ ನಿಧಿಗೆ ಸೇರಿಸು ಸತತ ಸಂದೇಶಗಳ ನಡುವಿನ ಗರಿಷ್ಠ ಮಧ್ಯಂತರವನ್ನು ಪ್ರತಿನಿಧಿಸುವ ಸಹಿ ಮಾಡಿದ ಪೂರ್ಣಾಂಕವಾಗಿದೆ. NTP ಕ್ಲೈಂಟ್ ಇಲ್ಲಿ ಸರ್ವರ್ ಅನ್ನು ಪೋಲ್ ಮಾಡಲು ನಿರೀಕ್ಷಿಸುವ ಮಧ್ಯಂತರವನ್ನು ನಿರ್ದಿಷ್ಟಪಡಿಸುತ್ತದೆ ಮತ್ತು NTP ಸರ್ವರ್ ಯಾವ ಮಧ್ಯಂತರವನ್ನು ಪೋಲ್ ಮಾಡಲು ನಿರೀಕ್ಷಿಸುತ್ತದೆ ಎಂಬುದನ್ನು ನಿರ್ದಿಷ್ಟಪಡಿಸುತ್ತದೆ. ಮೌಲ್ಯವು ಸೆಕೆಂಡುಗಳ ಬೈನರಿ ಲಾಗರಿಥಮ್‌ಗೆ ಸಮಾನವಾಗಿರುತ್ತದೆ.
ನಿಖರವಾದ (ನಿಖರತೆ) ಸಿಸ್ಟಂ ಗಡಿಯಾರದ ನಿಖರತೆಯನ್ನು ಪ್ರತಿನಿಧಿಸುವ ಸಹಿ ಮಾಡಿದ ಪೂರ್ಣಾಂಕವಾಗಿದೆ. ಮೌಲ್ಯವು ಸೆಕೆಂಡುಗಳ ಬೈನರಿ ಲಾಗರಿಥಮ್‌ಗೆ ಸಮಾನವಾಗಿರುತ್ತದೆ.
ರೂಟ್ ವಿಳಂಬ (ಸರ್ವರ್ ವಿಳಂಬ) - ಗಡಿಯಾರದ ವಾಚನಗೋಷ್ಠಿಗಳು NTP ಸರ್ವರ್ ಅನ್ನು ತಲುಪಲು ತೆಗೆದುಕೊಳ್ಳುವ ಸಮಯ, ಸೆಕೆಂಡ್‌ಗಳ ಸ್ಥಿರ-ಪಾಯಿಂಟ್ ಸಂಖ್ಯೆ.
ರೂಟ್ ಪ್ರಸರಣ (ಸರ್ವರ್ ಸ್ಪ್ರೆಡ್) - NTP ಸರ್ವರ್ ಗಡಿಯಾರದ ವಾಚನಗೋಷ್ಠಿಗಳು ಸ್ಥಿರ ಬಿಂದುವಿನೊಂದಿಗೆ ಹಲವಾರು ಸೆಕೆಂಡುಗಳಂತೆ ಹರಡುವಿಕೆ.
ರೆಫ್ ಐಡಿ (ಮೂಲ ಗುರುತಿಸುವಿಕೆ) - ಗಡಿಯಾರ ಐಡಿ. ಸರ್ವರ್ ಸ್ಟ್ರಾಟಮ್ 1 ಅನ್ನು ಹೊಂದಿದ್ದರೆ, ನಂತರ ref id ಪರಮಾಣು ಗಡಿಯಾರದ ಹೆಸರು (4 ASCII ಅಕ್ಷರಗಳು). ಸರ್ವರ್ ಮತ್ತೊಂದು ಸರ್ವರ್ ಅನ್ನು ಬಳಸಿದರೆ, ರೆಫ್ ಐಡಿ ಈ ಸರ್ವರ್‌ನ ವಿಳಾಸವನ್ನು ಹೊಂದಿರುತ್ತದೆ.
ಕೊನೆಯ 4 ಕ್ಷೇತ್ರಗಳು ಸಮಯವನ್ನು ಪ್ರತಿನಿಧಿಸುತ್ತವೆ - 32 ಬಿಟ್ಗಳು - ಪೂರ್ಣಾಂಕ ಭಾಗ, 32 ಬಿಟ್ಗಳು - ಭಾಗಶಃ ಭಾಗ.
ರೆಫರೆನ್ಸ್ - ಸರ್ವರ್‌ನಲ್ಲಿ ಇತ್ತೀಚಿನ ಗಡಿಯಾರ ವಾಚನಗೋಷ್ಠಿಗಳು.
ಹುಟ್ಟು – ಪ್ಯಾಕೆಟ್ ಕಳುಹಿಸಿದ ಸಮಯ (ಸರ್ವರ್‌ನಿಂದ ತುಂಬಿದೆ - ಈ ಕೆಳಗೆ ಇನ್ನಷ್ಟು).
ಸ್ವೀಕರಿಸಿ - ಪ್ಯಾಕೆಟ್ ಅನ್ನು ಸರ್ವರ್ ಸ್ವೀಕರಿಸಿದ ಸಮಯ.
ಪ್ರಸಾರ - ಪ್ಯಾಕೆಟ್ ಅನ್ನು ಸರ್ವರ್‌ನಿಂದ ಕ್ಲೈಂಟ್‌ಗೆ ಕಳುಹಿಸುವ ಸಮಯ (ಕ್ಲೈಂಟ್‌ನಿಂದ ತುಂಬಿದೆ, ಈ ಕೆಳಗೆ ಇನ್ನಷ್ಟು).

ನಾವು ಕೊನೆಯ ಎರಡು ಕ್ಷೇತ್ರಗಳನ್ನು ಪರಿಗಣಿಸುವುದಿಲ್ಲ.

ನಮ್ಮ ಪ್ಯಾಕೇಜ್ ಅನ್ನು ಬರೆಯೋಣ:

ಪ್ಯಾಕೇಜ್ ಕೋಡ್

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

ಪ್ಯಾಕೆಟ್ ಅನ್ನು ಸರ್ವರ್‌ಗೆ ಕಳುಹಿಸಲು (ಮತ್ತು ಸ್ವೀಕರಿಸಲು), ನಾವು ಅದನ್ನು ಬೈಟ್ ಅರೇ ಆಗಿ ಪರಿವರ್ತಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತದೆ.
ಈ (ಮತ್ತು ರಿವರ್ಸ್) ಕಾರ್ಯಾಚರಣೆಗಾಗಿ, ನಾವು ಎರಡು ಕಾರ್ಯಗಳನ್ನು ಬರೆಯುತ್ತೇವೆ - ಪ್ಯಾಕ್ () ಮತ್ತು ಅನ್ಪ್ಯಾಕ್ ():

ಪ್ಯಾಕ್ ಕಾರ್ಯ

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

ಅನ್ಪ್ಯಾಕ್ ಕಾರ್ಯ

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)

ಸರ್ವರ್‌ಗೆ ಪ್ಯಾಕೇಜ್ ಕಳುಹಿಸಲಾಗುತ್ತಿದೆ

ತುಂಬಿದ ಕ್ಷೇತ್ರಗಳೊಂದಿಗೆ ಪ್ಯಾಕೆಟ್ ಅನ್ನು ಸರ್ವರ್ಗೆ ಕಳುಹಿಸಬೇಕು ಆವೃತ್ತಿ, ಕ್ರಮದಲ್ಲಿ и ಪ್ರಸಾರ. ದಿ ಪ್ರಸಾರ ನೀವು ಸ್ಥಳೀಯ ಗಣಕದಲ್ಲಿ ಪ್ರಸ್ತುತ ಸಮಯವನ್ನು ನಿರ್ದಿಷ್ಟಪಡಿಸಬೇಕು (ಜನವರಿ 1, 1900 ರಿಂದ ಸೆಕೆಂಡುಗಳ ಸಂಖ್ಯೆ), ಆವೃತ್ತಿ - 1-4 ರಲ್ಲಿ ಯಾವುದಾದರೂ, ಮೋಡ್ - 3 (ಕ್ಲೈಂಟ್ ಮೋಡ್).

ಸರ್ವರ್, ವಿನಂತಿಯನ್ನು ಸ್ವೀಕರಿಸಿದ ನಂತರ, NTP ಪ್ಯಾಕೆಟ್‌ನಲ್ಲಿರುವ ಎಲ್ಲಾ ಕ್ಷೇತ್ರಗಳನ್ನು ಭರ್ತಿ ಮಾಡುತ್ತದೆ, ಕ್ಷೇತ್ರಕ್ಕೆ ನಕಲಿಸುತ್ತದೆ ಹುಟ್ಟು ನಿಂದ ಮೌಲ್ಯ ಪ್ರಸಾರ, ಇದು ವಿನಂತಿಯಲ್ಲಿ ಬಂದಿದೆ. ಕ್ಲೈಂಟ್ ತಕ್ಷಣವೇ ಕ್ಷೇತ್ರದಲ್ಲಿ ತನ್ನ ಸಮಯದ ಮೌಲ್ಯವನ್ನು ಏಕೆ ತುಂಬಲು ಸಾಧ್ಯವಿಲ್ಲ ಎಂಬುದು ನನಗೆ ಒಂದು ನಿಗೂಢವಾಗಿದೆ ಹುಟ್ಟು. ಪರಿಣಾಮವಾಗಿ, ಪ್ಯಾಕೆಟ್ ಹಿಂತಿರುಗಿದಾಗ, ಕ್ಲೈಂಟ್ 4 ಸಮಯ ಮೌಲ್ಯಗಳನ್ನು ಹೊಂದಿದೆ - ವಿನಂತಿಯನ್ನು ಕಳುಹಿಸಿದ ಸಮಯ (ಹುಟ್ಟು), ಸರ್ವರ್ ವಿನಂತಿಯನ್ನು ಸ್ವೀಕರಿಸಿದ ಸಮಯ (ಸ್ವೀಕರಿಸಿ), ಸರ್ವರ್ ಪ್ರತಿಕ್ರಿಯೆಯನ್ನು ಕಳುಹಿಸಿದ ಸಮಯ (ಪ್ರಸಾರ) ಮತ್ತು ಕ್ಲೈಂಟ್ ಪ್ರತಿಕ್ರಿಯೆಯನ್ನು ಸ್ವೀಕರಿಸಿದ ಸಮಯ - ಆಗಮನ (ಪ್ಯಾಕೇಜ್‌ನಲ್ಲಿಲ್ಲ). ಈ ಮೌಲ್ಯಗಳನ್ನು ಬಳಸಿಕೊಂಡು ನಾವು ಸರಿಯಾದ ಸಮಯವನ್ನು ಹೊಂದಿಸಬಹುದು.

ಪ್ಯಾಕೇಜ್ ಕೋಡ್ ಕಳುಹಿಸುವುದು ಮತ್ತು ಸ್ವೀಕರಿಸುವುದು

# 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) ರ ಹಳೆಯ ಸಮಸ್ಯೆಯಿಂದ ಇಂಗ್ಲಿಷ್ ಸಂಭಾವಿತ ವ್ಯಕ್ತಿಯ ಕ್ರಿಯೆಗಳಿಗೆ ಹೋಲುತ್ತದೆ: “ಒಬ್ಬ ಮನುಷ್ಯನಿಗೆ ಕೈಗಡಿಯಾರ ಇರಲಿಲ್ಲ, ಆದರೆ ಮನೆಯಲ್ಲಿ ನಿಖರವಾದ ಗೋಡೆಯ ಗಡಿಯಾರ ಇತ್ತು, ಅದನ್ನು ಅವನು ಕೆಲವೊಮ್ಮೆ ಮರೆತುಬಿಡುತ್ತಾನೆ. ಗಾಳಿಗೆ. ಒಂದು ದಿನ, ಮತ್ತೆ ತನ್ನ ಗಡಿಯಾರವನ್ನು ಸುತ್ತಿಕೊಳ್ಳುವುದನ್ನು ಮರೆತು, ಅವನು ತನ್ನ ಸ್ನೇಹಿತನನ್ನು ಭೇಟಿ ಮಾಡಲು ಹೋದನು, ಅವನೊಂದಿಗೆ ಸಂಜೆ ಕಳೆದನು ಮತ್ತು ಅವನು ಮನೆಗೆ ಹಿಂದಿರುಗಿದಾಗ, ಅವನು ವಾಚ್ ಅನ್ನು ಸರಿಯಾಗಿ ಹೊಂದಿಸುವಲ್ಲಿ ಯಶಸ್ವಿಯಾದನು. ಪ್ರಯಾಣದ ಸಮಯ ಮುಂಚಿತವಾಗಿ ತಿಳಿದಿಲ್ಲದಿದ್ದರೆ ಅವನು ಇದನ್ನು ಹೇಗೆ ನಿರ್ವಹಿಸುತ್ತಿದ್ದನು? ಉತ್ತರ ಹೀಗಿದೆ: “ಮನೆಯಿಂದ ಹೊರಡುವಾಗ, ಒಬ್ಬ ವ್ಯಕ್ತಿಯು ತನ್ನ ಗಡಿಯಾರವನ್ನು ಸುತ್ತುತ್ತಾನೆ ಮತ್ತು ಕೈಗಳು ಯಾವ ಸ್ಥಾನದಲ್ಲಿವೆ ಎಂಬುದನ್ನು ನೆನಪಿಸಿಕೊಳ್ಳುತ್ತಾನೆ. ಸ್ನೇಹಿತನ ಬಳಿಗೆ ಬಂದು ಅತಿಥಿಗಳನ್ನು ತೊರೆದ ನಂತರ, ಅವನು ಆಗಮನ ಮತ್ತು ನಿರ್ಗಮನದ ಸಮಯವನ್ನು ಗಮನಿಸುತ್ತಾನೆ. ಇದು ಅವರು ಎಷ್ಟು ಸಮಯದವರೆಗೆ ಭೇಟಿ ನೀಡುತ್ತಿದ್ದಾರೆಂದು ಕಂಡುಹಿಡಿಯಲು ಅನುವು ಮಾಡಿಕೊಡುತ್ತದೆ. ಮನೆಗೆ ಹಿಂತಿರುಗಿ ಗಡಿಯಾರವನ್ನು ನೋಡುತ್ತಾ, ಒಬ್ಬ ವ್ಯಕ್ತಿಯು ತನ್ನ ಅನುಪಸ್ಥಿತಿಯ ಅವಧಿಯನ್ನು ನಿರ್ಧರಿಸುತ್ತಾನೆ. ಈ ಸಮಯದಿಂದ ಅವನು ಭೇಟಿ ನೀಡಿದ ಸಮಯವನ್ನು ಕಳೆಯುವ ಮೂಲಕ, ಒಬ್ಬ ವ್ಯಕ್ತಿಯು ಅಲ್ಲಿಗೆ ಮತ್ತು ಹಿಂತಿರುಗಲು ಕಳೆದ ಸಮಯವನ್ನು ಕಂಡುಕೊಳ್ಳುತ್ತಾನೆ. ಅತಿಥಿಗಳನ್ನು ಬಿಡುವ ಸಮಯಕ್ಕೆ ರಸ್ತೆಯಲ್ಲಿ ಕಳೆದ ಅರ್ಧದಷ್ಟು ಸಮಯವನ್ನು ಸೇರಿಸುವ ಮೂಲಕ, ಮನೆಗೆ ಬರುವ ಸಮಯವನ್ನು ಕಂಡುಹಿಡಿಯಲು ಮತ್ತು ಅದಕ್ಕೆ ಅನುಗುಣವಾಗಿ ತನ್ನ ಗಡಿಯಾರದ ಕೈಗಳನ್ನು ಹೊಂದಿಸಲು ಅವನು ಅವಕಾಶವನ್ನು ಪಡೆಯುತ್ತಾನೆ.

ವಿನಂತಿಯ ಮೇರೆಗೆ ಸರ್ವರ್ ಕಾರ್ಯನಿರ್ವಹಿಸುತ್ತಿರುವ ಸಮಯವನ್ನು ಹುಡುಕಿ:

  1. ಕ್ಲೈಂಟ್‌ನಿಂದ ಸರ್ವರ್‌ಗೆ ಪ್ಯಾಕೆಟ್‌ನ ಪ್ರಯಾಣದ ಸಮಯವನ್ನು ಹುಡುಕಿ: ((ಆಗಮಿಸಿ - ಮೂಲ) - (ರವಾನೆ - ಸ್ವೀಕರಿಸಿ)) / 2
  2. ಕ್ಲೈಂಟ್ ಮತ್ತು ಸರ್ವರ್ ಸಮಯದ ನಡುವಿನ ವ್ಯತ್ಯಾಸವನ್ನು ಕಂಡುಹಿಡಿಯಿರಿ:
    ಸ್ವೀಕರಿಸಿ - ಮೂಲ - ((ಆಗಮಿಸಿ - ಮೂಲ) - (ರವಾನೆ - ಸ್ವೀಕರಿಸಿ)) / 2 =
    2 * ಸ್ವೀಕರಿಸಿ – 2 * ಮೂಲ – ಆಗಮನ + ಮೂಲ + ರವಾನಿಸು – ಸ್ವೀಕರಿಸಿ =
    ಸ್ವೀಕರಿಸಿ - ಹುಟ್ಟು - ಆಗಮಿಸಿ + ರವಾನಿಸಿ

ನಾವು ಫಲಿತಾಂಶದ ಮೌಲ್ಯವನ್ನು ಸ್ಥಳೀಯ ಸಮಯಕ್ಕೆ ಸೇರಿಸುತ್ತೇವೆ ಮತ್ತು ಜೀವನವನ್ನು ಆನಂದಿಸುತ್ತೇವೆ.

ಫಲಿತಾಂಶದ ಔಟ್ಪುಟ್

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)

ಉಪಯುಕ್ತ ಲಿಂಕ್.

ಮೂಲ: www.habr.com

ಕಾಮೆಂಟ್ ಅನ್ನು ಸೇರಿಸಿ