VB.NET SNTP Broadcast server






3.18/5 (4 votes)
Jul 25, 2006
2 min read

43302

1190
Broadcasting SNTP UDP packets using VB.NET
Introduction
I work a lot with industrial operator panels. These panels have a integrated Real Time Clock that sadly doesn't include Daylight Saving Time. So every time we gain or lose an hour, the RTC of the panels needs to be changed manually. The positive thing about these panels is that they support the SNTP protocol to synchronise their RTC with a server. For a panel to actually sync it's RTC it needs to receive a SNTP packet that is broadcasted over the network by a SNTP server.
Looking at the SNTP protocol I thought it shouldn't be to difficult to code a very simple SNTP server myself. The demo application will periodically broadcast a SNTP packet containing the system date and time over the network.
Using the code
The demo application needs three command line arguments to function correctly.
- Broadcast IP address
- Broadcast port number (Default is 123 according to RFC2030)
- Broadcast interval (in seconds)
' Check the number of command line arguments provided
If UBound(Environment.GetCommandLineArgs) = 3 Then
No further validation on these command line arguments is done. I leave this up to you.
The application uses the UdpClient class to broadcast the SNTP packet over the network.
' Set the UdpClient
Dim sntpServer As UdpClient
sntpServer = New UdpClient(Environment.GetCommandLineArgs(1), _
Convert.ToInt16(Environment.GetCommandLineArgs(2)))
Now for the interesting part. (at least for me it was).
A loop is started that will build and send the actual SNTP packet.
The packet is 48 bytes in total but most of these could be left empty for my application. This might not fully comply with the RFC2030 but for me it worked fine.
The number of seconds between 01/01/1900 and the current system date/time need to be calculated and set to bytes 40 to 43 before the packet can be send.
' Get the number of seconds from 1/1/1900 till now.
Dim ts As TimeSpan = DateTime.Now - New DateTime(1900, 1, 1)
Dim tsHex As String = Hex(ts.TotalSeconds)
Dim packet(47) As Byte
' Set information in bytes
packet(0) = 37 ' LI = 0, VN = 4, Mode 5 (Broadcast).
packet(1) = 2 ' Stratum.
packet(2) = 10 ' Poll.
packet(3) = 250 ' Precision.
't(4) -> t(39) are left empty.
packet(40) = Convert.ToByte(tsHex.Substring(0, 2), 16) ' Transmit timestamp.
packet(41) = Convert.ToByte(tsHex.Substring(2, 2), 16) ' Transmit timestamp.
packet(42) = Convert.ToByte(tsHex.Substring(4, 2), 16) ' Transmit timestamp.
packet(43) = Convert.ToByte(tsHex.Substring(6, 2), 16) ' Transmit timestamp.
't(44) -> t(47) are left empty.
Now the packet is broadcasted and the settings are printed to the console.
' Broadcast the SNTP packet.
sntpServer.Send(packet, packet.Length)
' Write date/time to console line.
Console.Clear()
Call PrintSettings(Environment.GetCommandLineArgs)
Console.WriteLine("Packet send at: " & DateTime.Now)
Finally the thread is kept asleep during the interval time.
' Sleep for interval time.
Thread.Sleep(Convert.ToInt16(Environment.GetCommandLineArgs(3)) * 1000)
History
25/07/2006, Version 1.0.0 : Initial post