LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

help with connecting to NIST NTP server on port 123

Solved!
Go to solution

I can get NIST time in Daytime format using the rt_nist_date_time.llb example posted on ni.com, but I cannot connect to NIST NTP format time data using port 123.  I freely admit to being over my head with this stuff, and have spent much of this Thanksgiving holiday reading about UDP and TCP.

 

The attached vi summarizes what I've tried so far.  The UDP case is what I thought would work, but I can't come up with a network address that the UDP-open vi likes.  Can anyone out there help this n00b tell the time?

 

The attached file is supposed to be in 8.0 format, although I'm working in 9.0

 

Here is a link discussing the time formats: http://tf.nist.gov/service/its.htm 

 

Jeff 

0 Kudos
Message 1 of 19
(16,742 Views)

Check the help for the UDP functions!

 

The network address for UDP open is optional, and only needed if your computer has multiple network interfaces configured. It has nothing to do with your remote server. UDP is a connectioness protocol.

 

You need four steps:

  1. UDP open: Wire 0 to the port. This is the local port used to listen for return traffic. If you set ot to zero, the OS will pick an unused port. The "port" output will tell you which port is actually used.
  2. UDP write: Here you send the NTP request to the server. Use port 123 and your time server as server. Sorry, I don't know the format of the request string.
  3. UDP read: here you read the response from the time server as you currently do.
  4. UDP Close: follow it by a UDP close.

 

0 Kudos
Message 2 of 19
(16,729 Views)

OK, some digging on the web allowed me to get it working. See if you can parse the resulting string. 😉

 

(no guarantees.... ;))

 

Message Edited by altenbach on 11-26-2009 10:10 PM
Download All
Message 3 of 19
(16,726 Views)
Solution
Accepted by topic author jstevens

altenbach wrote:

See if you can parse the resulting string. 😉


OK, things seem to work. Here's how to parse the entire NTP packet. Of course if you only want the timestamp, you could just parse the desired substring and eliminate a lot of bulk.

 

Things are a bit tricky because the timestamp differs by 4 years from the LabVIEW definition and is in 32.32 FXP representation. If you don't care about fractional seconds, you could just parse the 32 bit integer part for even simpler code.

 

(I wrote this between turkey and dessert, so please make sure it's all correct. 😮 Modify as needed. :D)

Message 4 of 19
(16,714 Views)

THANK YOU!!!  I don't think I ever would have come up with connecting the web address to a Read or Write UDP rather than the Open UDP block.  Not to mention starting by opening port zero.  FWIW, I did read the UDP help, as well as all the KB and forum information I could find, but it all added up to an incomplete understanding of how to arrange the blocks and what to feed them.

 

Your cluster approach to parsing is a lesson I'll keep at my fingertips - much simpler than my endless string of match-pattern filters!

 

Thanks again!

 

Jeff, (aka Roger the Shrubber )

0 Kudos
Message 5 of 19
(16,694 Views)
For even more precision, you can account for the packet delay, by adding a local timestamp to the request (field: transmit timestamp). This same value will be returned by the server as "originate timestamp". Take another timestamp when the return packet is received. Some simple math allows you to account for the roundtrip delay and adjust the received value accordingly (once you receive the packet, some time has already passed, so the direct time value is actually stale by a fraction of a second).
Message 6 of 19
(16,690 Views)

jstevens wrote:

THANK YOU!!!  I don't think I ever would have come up with connecting the web address to a Read or Write UDP rather than the Open UDP block.  Not to mention starting by opening port zero.


Unlike TCP, UDP is a connectionless protocol. Here's a quick explanation in different words.

 

  • A udp packet travels from a [sourceIP, sourcePort] to a [DestinationIP, destinationPort].
  • UDP open basically reserves a local port used for sending (soucePort) and receiving (incoming packet with that same destinationPort). Since some local ports are always in use, you would generate an error if you would accidentally pick a used port. Picking zero is useful for requests (as in this case!), because the OS will pick an unused ephemeral port. The actual source port number does not matter because the NTP server will just send the reply packet back to whatever port it came from. (If you would write your own NTP server in LabVIEW, you would of course need to set the local port to 123, and would get a conflict if another NTP server is already running on your rig). Writing an NTP server in LabVIEW would be a trivial modification to the current code, try it! :). Simply listen for packets on port 123, form a response packet based on the timestamp, and send it to whatever IP/Port it came from (that info is available from udp read) and then go back to listen for new requests.).
  • UDP write sends a packet to the server using the above opened local port as source port. You can use the same connectionID to write to several other servers and ports, because UDP is connectionless. (TCP is connection based, so a TCP connection involves a defined source/destination pair)
  • UDP read listens for incoming packets from all over the world at that same local port. It is very unlikely, but theoretically possible that other UDP packets will arrive at that same port, so you could even filter to make sure to read incoming packets until they match the port and IP of the original request. The current code is somewhat vulnerable to a DOS (denial of service) attack for example as follows: Imagine the guy in the next cubicle had means of sniffing your network traffic. He could write a small program that looks for your NTP requests and then immediately starts flooding your IP with meaningless UDP packets to the sourcePort you just used. The current program only reads one packet and thus will never see the return packet from the NTP server.
  • UDP close frees up the local port and the computer is now no longer listening for packets on that port. Of course you could keep the port open for the duration of the program, especially if you intend to send UDP request once in a while during execution.

 

Makes sense? 🙂

Message 7 of 19
(16,677 Views)

I tried the program but it failed on UDP read, any suggestion ?

0 Kudos
Message 8 of 19
(16,145 Views)

 


@jimwu wrote:

I tried the program but it failed on UDP read, any suggestion ?


 

First suggestion: "failed" is not good enough to troubleshoot. Please provide the actual error code. I am guessing that it timed out, meaning that no response came back. This could have many reasons.

 

 

  • You entered the IP address of a server that does not run an NTP service.
  • The NTP server refused to reply to you. They may only respond to queries from the same country, for example.
  • The query or response got blocked elsewhere (corporate firewall, etc.)
My suggestion would be to pick the IP address of a known good NTP server near you and try again. Good luck!

 

0 Kudos
Message 9 of 19
(16,127 Views)

Also make sure to enter the IP address correctly. In the original program, the string entry box was not limited to a single line, making entry errors more likely. Here's a new version where the IP address is limited to a single line.

 

 

 

Message 10 of 19
(16,121 Views)