+1 vote
by (230 points)

When calling this:

Ntp.SynchronizeSystemClock("pool.ntp.org");

Then it sometimes works, but often it does not correct the time and we get an exception instead one minute after the call:

NtpException: Request timed out - no answer in 60000 ms

How can we reliably correct UTC on the device?

Applies to: Rebex Time

1 Answer

+1 vote
by (58.9k points)
selected by
 
Best answer

The error that you get "NtpException: Request timed out - no answer in 60000 ms" means that we did not receive response for the request of our client. Some of the time servers we encountered are sometimes not reliable enough. Simply said the unreliability can be solved by using a try catch block and retrying the method that throw error.

Actually, the static method Ntp.SynchronizeSystemClock combines two things. First it connects to the NTP server and second it gets the time from the server and synchronizes the device time then.

I don't know what part fails in your case, to find out it would be good to use the non-static method (just create instance of Ntp and then call the SynchronizeSystemClock on it).

You could then retry the critical methods for instance like this:

// connects to the server. THe method retries it 3 times before giving up
Ntp ntp = ConnectToNtpRetryOnTimeoutFailure("pool.ntp.org");

// receives actual time from the server
// this method can also timeout in case the server does not respond within the ntp.Timeout range (in miliseconds)
// you might want to retry the SynchronizeSystem clock operation in the same fashion if it causes problems:
ntp.SynchronizeSystemClock();


private Ntp ConnectToNtpRetryOnTimeoutFailure(string server)
{
    int cnt_max = 3;
    Ntp ntp = null;

    for (int i = 0; i < cnt_max; i++)
    {
        try
        {
            ntp = new Ntp(server);
            break;
        }
        catch (NtpException ex)
        {
            // NtpException: Request timed out -no answer in 60000 ms
            if (!ex.Message.StartsWith("Request timed out"))
                throw;

            if (i + 1 == cnt_max)
                throw new ApplicationException(string.Format("Unable to connect to NTP server (retried {0} times). Error {1}", cnt_max, ex.ToString()));

            continue;
        }
    }
    return ntp;
}

Please give the code above a try and let me know whether retrying the operation helps.

by (230 points)
The first part of connecting to a server happens very fast, but the second part times out. Turns out the issue arises because the client machine we are testing on runs ESET Smart Security http://www.eset.co.uk/Home/Smart-Security and presumably blocks the incoming UDP transport required for NTP to work. Funnily, it is the ESET Antivirus featureset not the ESET firewall featureset that does the blocking somehow. This puts us in a difficult situation, because we cannot ask our clients to configure their firewalls or antivirus solutions, correcting UTC needs to work without local user intervention. So the only idea right now is to use the Time or the Daytime protocol, but the blocker there is we could not find any servers we could use these protocols with? Do you know any (reliable) Daytime or Time servers we could use?
by (58.9k points)
You could use Time or Daytime but keep in mind that they are actually not as precise as the NTP protocol (due to the fact that it runs over UDP actually). It also consumes more traffic than the NTP protocol.

Sorry we do not maintain list of publicly accessible Time/Daytime servers. I think it would be best to install your own Time or Daytime server (the server could internally sync the time via the precise NTP protocol). This way you would have the server under control and not rely on third party servers.
...