0

Possible Duplicate:
How to Query an NTP Server from C#

I'm trying get the datetime from time.windows.com NTP server, I'm using the following code:

using System;
using System.IO;
using System.Net.Sockets;

namespace ntpdate2
{
    class MainClass
    {
        public static void Main (string[] args)
        {
            var client = new TcpClient("time.windows.com", 123);
            client.SendTimeout = 60;
            using (var streamReader = new StreamReader(client.GetStream()))
            {
                var response = streamReader.ReadToEnd();
                Console.WriteLine(response);
                streamReader.Close();
            }



        }
    }
}

But it gives an:

Unhandled Exception: System.Net.Sockets.SocketException: Connection timed out
  at System.Net.Sockets.Socket.Connect (System.Net.EndPoint remote_end) [0x00000] 
  at System.Net.Sockets.TcpClient.Connect (System.Net.IPEndPoint remote_end_point) [0x00000] 
  at System.Net.Sockets.TcpClient.Connect (System.Net.IPAddress[] ipAddresses, Int32 port) [0x00000] 
The application was terminated by a signal: SIGHUP

How to fix this? thanks in advance.

Community
  • 1
  • 1
Jack
  • 16,276
  • 55
  • 159
  • 284
  • NTP is a UDP protocol, not TCP. – Hans Passant May 26 '12 at 19:26
  • @KenWhite: it works for you? I have tried by using similar code, but I get an "infinite loop" instead of exception above. – Jack May 26 '12 at 19:38
  • I presume it works, since the answer was accepted and has received 16 upvotes. I don't have time to personally test every single question and answer, I'm afraid. :-) The second answer there also has a link to other examples of using the same solution that has upvotes as well. – Ken White May 26 '12 at 19:58
  • Tested, the code linked there works. – yamen May 26 '12 at 21:05

1 Answers1

5

Here is code that runs in LINQPad, slightly modified from the original version at https://mschwarztoolkit.svn.codeplex.com/svn/NTP/NtpClient.cs

void Main()
{
    var x = NtpClient.GetNetworkTime();
   x.Dump();
}

/// <summary>
/// Static class to receive the time from a NTP server.
/// </summary>
public class NtpClient
{
    /// <summary>
    /// Gets the current DateTime from time-a.nist.gov.
    /// </summary>
    /// <returns>A DateTime containing the current time.</returns>
    public static DateTime GetNetworkTime()
    {
        return GetNetworkTime("time.windows.com"); // time-a.nist.gov
    }

    /// <summary>
    /// Gets the current DateTime from <paramref name="ntpServer"/>.
    /// </summary>
    /// <param name="ntpServer">The hostname of the NTP server.</param>
    /// <returns>A DateTime containing the current time.</returns>
    public static DateTime GetNetworkTime(string ntpServer)
    {
        IPAddress[] address = Dns.GetHostEntry(ntpServer).AddressList;

        if(address == null || address.Length == 0)
            throw new ArgumentException("Could not resolve ip address from '" + ntpServer + "'.", "ntpServer");

        IPEndPoint ep = new IPEndPoint(address[0], 123);

        return GetNetworkTime(ep);
    }

    /// <summary>
    /// Gets the current DateTime form <paramref name="ep"/> IPEndPoint.
    /// </summary>
    /// <param name="ep">The IPEndPoint to connect to.</param>
    /// <returns>A DateTime containing the current time.</returns>
    public static DateTime GetNetworkTime(IPEndPoint ep)
    {
        Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

        s.Connect(ep);

        byte[] ntpData = new byte[48]; // RFC 2030 
        ntpData[0] = 0x1B;
        for (int i = 1; i < 48; i++)
            ntpData[i] = 0;

        s.Send(ntpData);
        s.Receive(ntpData);

        byte offsetTransmitTime = 40;
        ulong intpart = 0;
        ulong fractpart = 0;

        for (int i = 0; i <= 3; i++)
            intpart = 256 * intpart + ntpData[offsetTransmitTime + i];

        for (int i = 4; i <= 7; i++)
            fractpart = 256 * fractpart + ntpData[offsetTransmitTime + i];

        ulong milliseconds = (intpart * 1000 + (fractpart * 1000) / 0x100000000L);
        s.Close();

        TimeSpan timeSpan = TimeSpan.FromTicks((long)milliseconds * TimeSpan.TicksPerMillisecond);

        DateTime dateTime = new DateTime(1900, 1, 1);
        dateTime += timeSpan;

        TimeSpan offsetAmount = TimeZone.CurrentTimeZone.GetUtcOffset(dateTime);
        DateTime networkDateTime = (dateTime + offsetAmount);

        return networkDateTime;
    }
}
dplante
  • 2,445
  • 3
  • 21
  • 27