Python Cookbook 2Nd Edition Jun 1002005 [Electronic resources]

David Ascher, Alex Martelli, Anna Ravenscroft

نسخه متنی -صفحه : 394/ 264
نمايش فراداده

Recipe 13.4. Getting Time from a Server via the SNTP Protocol

Credit: Simon Foster

Problem

You need to contact an SNTP (Simplified Network Time Protocol) server (which respects RFC 2030) to obtain the time of day as returned by that server.

Solution

SNTP is quite simple to implement, for example in a small script:

import socket, struct, sys, time
TIME1970 = 2208988800L                        # Thanks to F.Lundh
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
data = '\x1b' + 47 * '\0'
client.sendto(data, (sys.argv[1], 123))
data, address = client.recvfrom(1024)
if data:
print 'Response received from:', address
t = struct.unpack('!12I', data)[10]
t -= TIME1970
print '\tTime=%s' % time.ctime(t)

Discussion

An SNTP exchange begins with a client sending a 48-byte UDP datagram which starts with byte '\x1b'. The server answers with a 48-byte UDP datagram made up of twelve network-order longwords (4 bytes each). We can easily unpack the server's returned datagram into a tuple of ints, by using standard Python library module struct's unpack function. Then, for simplicity, we look only at the eleventh of those twelve longwords. That integer gives the time in secondsbut it measures time from an epoch that's different from the 1970-based one normally used in Python. The difference in epochs is easily fixed by subtracting the magic number (kindly supplied by F. Lundh) that is named TIME1970 in the recipe. After the subtraction, we have a time in seconds from the epoch that complies with Python's standard time module, and we can handle it with the functions in module time. In this recipe, we just display it on standard output as formatted by function time.ctime.

See Also

Documentation for the standard library modules socket, struct and time in the Library Reference and Python in a Nutshell; the SNTP protocol is defined in RFC 2030 (http://www.ietf.org/rfc/rfc2030.txt), and the richer NTP protocol is defined in RFC 1305 (http://www.ietf.org/rfc/rfc1305.txt); Chapter 3 for general issues dealing with time in Python.