如何在 Windows Azure 上使用 NTP 验证本地 VM 时钟?

发布于 2024-11-10 08:40:18 字数 551 浏览 3 评论 0原文

NTP(网络时间协议)基本上是调整设置服务器时钟的事实上的标准。我已经提出了一个关于native的期望的问题Windows Azure 上的时钟精度。这里有一个稍微不同的问题:如何使用 NTP 验证当前时钟的可靠性?问题是 UDP 在 Windows Azure 上不可用(仅 TCP),而且似乎有 NTP 没有可用的 TCP 实现(尽管讨论已经有近十年的历史了)。

有什么办法吗?

NTP (Network Time Protocol) is basically the de-facto standard to adjust setup server clocks. I have already raised a question about the expectations in terms of native clock accuracy on Windows Azure. Here comes a slightly different one: how I can validate the current clock reliability with NTP? The catch is that UDP is not available on Windows Azure (only TCP), and it seems there is no TCP implementation available of NTP (although the discussion is nearly one decade old).

Any take?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我恋#小黄人 2024-11-17 08:40:18

假设 UDP 传出数据包仍然被 Azure 阻止(我很惊讶/失望,情况仍然如此!)那么也许您可以使用分辨率较低的 TCP 服务,例如 TIME 或 DAYTIME - 请参阅 http://www.nist.gov/pml/div688/grp40/its.cfm - 您显然需要测量网络调用所花费的时间长度,以确保返回的答案对您来说足够准确。

Assuming that UDP outgoing packets are still blocked by Azure (I'm surprised/disappointed this is still the case!) then maybe you could drop down to a TCP service with less resolution such as TIME or DAYTIME - see descriptions of both on http://www.nist.gov/pml/div688/grp40/its.cfm - you would obviously need to measure the length of time your network call took in order to be sure the answer coming back is sufficiently accurate for you.

待"谢繁草 2024-11-17 08:40:18

Joannes 和 Stuart:您说得对,Windows Azure 角色(Web、Worker 和 VM 角色)当前不支持托管 UDP 端点。但是,Windows Azure 角色 VM 上已默认包含 NTP 支持,当前默认配置为每周一次与服务器 time.windows.com 同步时钟(证据 此处 - 搜索“时间服务”)。

如果每周同步不够频繁,您可以调整启动任务中的注册表设置。

哈!

Joannes and Stuart: You are correct that Windows Azure roles (Web, Worker, and VM Roles) do not support hosting of UDP endpoints currently. However, NTP support is already included by default on Windows Azure role VMs, currently configured by default to synch the clock against server time.windows.com once a week (evidence here - search for "time service").

You can tweak a registry setting in a Startup Task if a weekly sync is not frequent enough.

HTH!

っ〆星空下的拥抱 2024-11-17 08:40:18

我对你关于 udp 的回答感到有点惊讶,而我实际上是从我的 azure web 角色连接到 NTP 服务器来为我们的 JS 客户端同步提供服务。
这工作正常...

请注意,Azure Web 角色时间与 NTP 时间有很大不同(实际上提前了 30 秒!!)。但是,NTP 时间几乎与我的本地计算机与 time.microsoft.com 同步的时间相同

{"network":"2013-07-16T18:18:25.9558581Z","server":"2013-07-16T18:18:52.5415999Z"}

,这是我使用的代码:

    static uint SwapEndianness(ulong x)
    {
        return (uint)(((x & 0x000000ff) << 24) +
                       ((x & 0x0000ff00) << 8) +
                       ((x & 0x00ff0000) >> 8) +
                       ((x & 0xff000000) >> 24));
    }

    static DateTime Update(string server)
    {
        // NTP message size - 16 bytes of the digest (RFC 2030)
        var ntpData = new byte[48];

        //Setting the Leap Indicator, Version Number and Mode values
        ntpData[0] = 0x1B; //LI = 0 (no warning), VN = 3 (IPv4 only), Mode = 3 (Client Mode)

        var addresses = Dns.GetHostEntry(server).AddressList;

        //The UDP port number assigned to NTP is 123
        var ipEndPoint = new IPEndPoint(addresses[0], NTPPort);
        //NTP uses UDP
        var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

        socket.Connect(ipEndPoint);

        socket.Send(ntpData);
        DateTime l_now = DateTime.UtcNow;
        socket.Receive(ntpData);
        socket.Close();

        //Offset to get to the "Transmit Timestamp" field (time at which the reply 
        //departed the server for the client, in 64-bit timestamp format."
        const byte serverReplyTime = 40;

        //Get the seconds part
        ulong intPart = BitConverter.ToUInt32(ntpData, serverReplyTime);

        //Get the seconds fraction
        ulong fractPart = BitConverter.ToUInt32(ntpData, serverReplyTime + 4);

        //Convert From big-endian to little-endian
        intPart = SwapEndianness(intPart);
        fractPart = SwapEndianness(fractPart);

        var milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000L);

        //**UTC** time
        var l_networkTime = (new DateTime(_epocBaseTicks, DateTimeKind.Utc)).AddMilliseconds((long)milliseconds);
        _networkTimeDelta = l_networkTime.Ticks - l_now.Ticks ;
        return l_networkTime;
    }

希望有所帮助。

I'm a bit surprised by your answer about udp while i'm actually connect to NTP server from my azure web role to serve our JS client synchronization.
This is working fine...

Note the azure web role time is a lot different thant the NTP one ( actually 30s ahead !! ). However, the NTP time is nearly the same as my local machine synchronized with time.microsoft.com

{"network":"2013-07-16T18:18:25.9558581Z","server":"2013-07-16T18:18:52.5415999Z"}

Here the code i use :

    static uint SwapEndianness(ulong x)
    {
        return (uint)(((x & 0x000000ff) << 24) +
                       ((x & 0x0000ff00) << 8) +
                       ((x & 0x00ff0000) >> 8) +
                       ((x & 0xff000000) >> 24));
    }

    static DateTime Update(string server)
    {
        // NTP message size - 16 bytes of the digest (RFC 2030)
        var ntpData = new byte[48];

        //Setting the Leap Indicator, Version Number and Mode values
        ntpData[0] = 0x1B; //LI = 0 (no warning), VN = 3 (IPv4 only), Mode = 3 (Client Mode)

        var addresses = Dns.GetHostEntry(server).AddressList;

        //The UDP port number assigned to NTP is 123
        var ipEndPoint = new IPEndPoint(addresses[0], NTPPort);
        //NTP uses UDP
        var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

        socket.Connect(ipEndPoint);

        socket.Send(ntpData);
        DateTime l_now = DateTime.UtcNow;
        socket.Receive(ntpData);
        socket.Close();

        //Offset to get to the "Transmit Timestamp" field (time at which the reply 
        //departed the server for the client, in 64-bit timestamp format."
        const byte serverReplyTime = 40;

        //Get the seconds part
        ulong intPart = BitConverter.ToUInt32(ntpData, serverReplyTime);

        //Get the seconds fraction
        ulong fractPart = BitConverter.ToUInt32(ntpData, serverReplyTime + 4);

        //Convert From big-endian to little-endian
        intPart = SwapEndianness(intPart);
        fractPart = SwapEndianness(fractPart);

        var milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000L);

        //**UTC** time
        var l_networkTime = (new DateTime(_epocBaseTicks, DateTimeKind.Utc)).AddMilliseconds((long)milliseconds);
        _networkTimeDelta = l_networkTime.Ticks - l_now.Ticks ;
        return l_networkTime;
    }

Hope this help.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文