SNTP Time Class
Written by Harry Fairhead   
Tuesday, 23 December 2014
Article Index
SNTP Time Class
Time Stamps
Getting the Time

Getting The Time

Now we can wait for the time server to send a datagram back to us. First we need to initialise a new IPEndPoint object and a new SNTPpacket for the reply. We could reuse the old SNTP packet if you are trying to save time and storage.

IPEndPoint remoteEP=
          new IPEndPoint(IPAddress.Any,0);
SNTPpacket reply=new SNTPpacket();

Again for simplicity we use the blocking form of the receive method. Notice that this will hang forever if no packets are recieved back from the time server. In practice a much better idea is to use the non-blocking BeginRecieve method:

reply.buffer =UDP.Receive(ref remoteEP);

Now we can process the data in the buffer, assuming that a datagram was received and place the results in the SNTPpacket properties, again using a method we have yet to write:

 reply.ConvertFromBuffer();
 return reply;
}

We have to now write the ConvertFromBuffer method and this is slightly more complicated than the ConvertToBuffer method. However converting the first four bytes is easy enough and more or less just a reversal of the ConverToBuffer method.

public void ConvertFromBuffer(){
 Mode =(byte)( buffer[0] & 0x7);
 VN = (byte)((buffer[0] >>3) & 0x7);
 LI = (byte)((buffer[0] >>6) & 0x3);
 Stratum = buffer[1];
 Poll = buffer[2];
 Precision = buffer[3];

The next three 32bit values are also easy enough as we do not attempt any data conversions to more sophisticated data types:

RootDelay =convertInt32(4);
RootDispersion = convertInt32(8);
RefId = Encoding.ASCII.GetString(buffer,12,4);

Next we have to convert the 64 bit time values and transfer them to the DateTime properties. Again it is simpler to suppose that we have a method that does the job and solve the problem of writing it later:

RefTimeStamp = ConvertFromSNTPTime(16);
OriginateTimeStamp = ConvertFromSNTPTime(24);
ReceiveTimeStamp = ConvertFromSNTPTime(32);
TransmitTimeStamp = ConvertFromSNTPTime(40);

where the ConvertFromSNTPTime(start) method converts the 8 bytes starting the "start" position in the buffer.

Finally we need to write the ConvertFromSNTPTime method.

Again this is complicated by the need to reverse the byte order as we unpack the buffer into two temporary arrays one for the high value i.e. the integer number of seconds and one for the low value the fractional seconds:

private DateTime ConvertFromSNTPTime(int start){
 byte[] tempHigh=new byte[4];
 byte[] tempLow = new byte[4];
 for (int i = 0; i < 4; i++){
  tempHigh[i]=buffer[start + 3 - i];
  tempLow[i]=buffer[start + 4 + 3 - i];
 }

Now that the byte order is reversed we can use BitConverter to get the high and low 32bits into unsigned 32 bit integers:

UInt32 tempTime = BitConverter.ToUInt32(
                              tempHigh, 0);
UInt32 tempFrac = BitConverter.ToUInt32(
                              tempLow, 0);

To convert this raw second count into a DateTime we can make things easy by first converting to a double that represents the total number of seconds, including any fractional portion since 1 Jan 1900:

double SNTPTime = tempTime+
          ((double)tempFrac)/
             ((double)UInt32.MaxValue+1);

Now we can convert this to a DateTime object and add the appropriate number of seconds to the start of the SNTP time count i.e. 1 Jan 1990:

 return new DateTime(1900, 1, 1).
 AddSeconds(SNTPTime);
}

 

This completes the unpacking and all of the methods we have assumed were available have been written - time to try it all out.

Trying it out

Now we can try out the control. Add a command button the Form  project and enter the following code:

private void button1_Click(
        object sender,
        RoutedEventArgs e){
 SNTP SntpTime = new SNTP();
 SntpTime.TimeServer = "pool.ntp.org";
 SNTP.SNTPpacket time=SntpTime.SNTPRequest();
 Console.WriteLine(
 time.TransmitTimeStamp.ToString());
 Console.WriteLine(time.RefId);
 Console.WriteLine(
 time.Stratum.ToString());
}

pool.,ntp.org uses a public server from the pool using a round robin algorithm. You can use any server you care to. 

If you need to know more, or find a more local server, look at http://www.ntp.org/ .

 

Code for this project is available from the CodeBin

Related Articles

C# Bit Bashing - The BitConverter       

Hexadecimal       

Binary - Negative Numbers       

JavaScript Bit Manipulation     

 

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.

 


The Minimum Spanning Tree - Prim's Algorithm In Python

Finding the minimum spanning tree is one of the fundamental algorithms and it is important in computer science and practical programming. We take a look at the theory and the practice and discover how [ ... ]



QuickSort Exposed

QuickSort was published in July 1961 and so is celebrating its 60th birthday.  QuickSort is the most elegant of algorithms and every programmer should study it. It is also subtle and this often m [ ... ]


Other Projects

 

raspberry pi books

 

Comments




or email your comment to: comments@i-programmer.info

 

<ASIN:0201633469>

<ASIN:159327047X>

<ASIN:1590594843>

<ASIN:1402078838>



Last Updated ( Sunday, 16 September 2018 )