Page 1 of 4
SNTP is a network protocol for obtaining an accurate time and it is an interesting exercise to build an SNTP client. In this article the language used is C# but it is easy enough to generalise to a language of your choice and extend the ideas to an SNTP server if you need to. The main aim is to describe and show how to implement the basic protocol.
To start at the beginning I'd better tell you what SNTP is all about. All over the Internet there are servers which transmit the accurate time using different types of clock including some very accurate atomic clocks. In practice it doesn't really matter what type of clock is being used because almost anything is going to be more accurate than your system hardware clock which typically loses minutes every day! However most modern operating systems do include the ability to synchronise the system clock with an SNTP time server and so your system clock might well be more accurate than its hardware specification would suggest.
The idea is that you can connect to one of these servers and simply request the time be sent to you. The protocol used for the request and the delivery is SNTP, Simple Network Time Protocol, or NTP, Network Time Protocol.
This isn't a complicated protocol but implementing the client described took far longer than you might guess. The reason is, as always, that the protocol is described in a way that makes good sense to the protocol specification writer but leaves a lot vague and unclear.
There are two versions of SNTP, Unicast and Multicast.
The Mulitcast protocol broadcasts time packets that anyone can pick up and is useful for keeping a local network synchronised. The Unicast protocol is slightly more complicated from the client's point of view in that it has to request a packet but it is the norm on the wider Internet.
To make use of Unicast SNTP we have to use the datagram or UDP protocol as opposed to a TCP connection. The simplest way of working with UDP in .NET is to use the UdpClient class but this is just a customisation of the more fundamental Socket class and you can easily use the Socket class to work with UDP if you want to.
The basic transaction is simple.
The client sends an SNTP data structure as UDP packet using port 123 to the server.
The server then sends an SNTP data structure as a UDP packet back using the same port to the client.
The structure of time
Sounds too good to be true, and indeed it is easy, but the complications are hidden in the words "SNTP data structure".
The structure consists of four 32-bit words followed by four 64-bit time stamps. There is also an optional 96-bit authenticator, which can be used to verify the server's identity, but this isn't used by publicly available time servers.
The SNTP time packet
Each of the time stamps uses the same 64-bit format.
The first 32 bits is an unsigned binary integer that gives the number of seconds since 00h on 1 Jan 1900. The next 32 bits is a pure binary fraction giving the fractional part of the seconds since the fiducial date.
Most time standards aren't accurate enough to fill the entire 32 bits and any unused bits are simply set to zero.
Time Stamp format
Interestingly there is a problem contained in this time stamp format that is very similar to the year 2000 problem. Yes, you've guessed it – roll over! Currently the high bit of the time stamp is set and it is heading to roll over in 2036 so look out for the Y2036 bug problem.
Ignoring this little problem for the moment, we are still left with a few simple practical difficulties. For example, what time zone does the time stamp represent?
The answer is that it doesn't reflect any time zone, the time stamp is always UT or Universal Time (which is the same as GMT, Greenwich Mean Time)
Our time control is just going to ignore other time zones and will return UT no matter what time zone is in use.
The final problem with the time stamp, and it is the problem with all such specifications, is the byte and bit order of the data. Although you can be reasonably certain of this using descriptions such as "high order bits to the right" and "Big Endian byte order" you can never be 100% sure that you have understood such a diagram and descriptions until you try it out.