Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#通用Windows应用程序如何从internet获取时间_C#_Datetime_Win Universal App_Windows 10 Universal_Windows 10 Iot Core - Fatal编程技术网

C#通用Windows应用程序如何从internet获取时间

C#通用Windows应用程序如何从internet获取时间,c#,datetime,win-universal-app,windows-10-universal,windows-10-iot-core,C#,Datetime,Win Universal App,Windows 10 Universal,Windows 10 Iot Core,我在运行Windows10IoT内核的Raspberry Pi3上遇到了问题,因为系统时钟会随着时间的推移明显漂移。我决定制作一个程序,将系统时钟设置回正确的时间,设备将从互联网上获取。我已经知道如何设置系统时钟,但问题是:在Windows 10 IoT core上运行C#Universal Windows应用程序时,如何从互联网获取精确的时间 为了从x86和x64上的windows time server获取时间,我以前做过以下工作: public static DateTime GetNet

我在运行Windows10IoT内核的Raspberry Pi3上遇到了问题,因为系统时钟会随着时间的推移明显漂移。我决定制作一个程序,将系统时钟设置回正确的时间,设备将从互联网上获取。我已经知道如何设置系统时钟,但问题是:在Windows 10 IoT core上运行C#Universal Windows应用程序时,如何从互联网获取精确的时间

为了从x86和x64上的windows time server获取时间,我以前做过以下工作:

public static DateTime GetNetworkTime()
{
    //default Windows time server
    const string ntpServer = "time.windows.com";

    // 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(ntpServer).AddressList;

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

    socket.Connect(ipEndPoint);

   //Stops code hang if NTP is blocked
   socket.ReceiveTimeout = 3000;     

   socket.Send(ntpData);
   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 networkDateTime = (new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc)).AddMilliseconds((long)milliseconds);

  return networkDateTime.ToLocalTime();
}

// stackoverflow.com/a/3294698/162671
static uint SwapEndianness(ulong x)
{
    return (uint) (((x & 0x000000ff) << 24) +
               ((x & 0x0000ff00) << 8) +
               ((x & 0x00ff0000) >> 8) +
               ((x & 0xff000000) >> 24));
}
publicstaticdatetime GetNetworkTime()
{
//默认Windows时间服务器
常量字符串ntpServer=“time.windows.com”;
//NTP消息大小-摘要的16字节(RFC 2030)
var ntpData=新字节[48];
//设置Leap指示器、版本号和模式值
ntpData[0]=0x1B;//LI=0(无警告),VN=3(仅限IPv4),Mode=3(客户端模式)
var addresses=Dns.GetHostEntry(ntpServer.AddressList);
//分配给NTP的UDP端口号为123
var ipEndPoint=新的ipEndPoint(地址[0],123);
//NTP使用UDP
var套接字=新套接字(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
插座连接(ipEndPoint);
//如果NTP被阻止,则停止代码挂起
socket.ReceiveTimeout=3000;
socket.Send(ntpData);
套接字接收(ntpData);
socket.Close();
//到达“传输时间戳”字段的偏移量(回复的时间
//以64位时间戳格式为客户端退出服务器。“
常量字节serverReplyTime=40;
//得到秒的部分
ulong intPart=BitConverter.ToUInt32(ntpData,serverReplyTime);
//得到秒分数
ulong fractPart=BitConverter.ToUInt32(ntpData,serverReplyTime+4);
//从大端到小端的转换
intPart=SwapEndianness(intPart);
fractPart=SwapEndianness(fractPart);
变量毫秒=(intPart*1000)+(fractPart*1000)/0x10000000L;
//**UTC**时间
var networkDateTime=(新的DateTime(1900,1,1,0,0,0,DateTimeKind.Utc)).addmillizes((长)毫秒);
返回networkDateTime.ToLocalTime();
}
//stackoverflow.com/a/3294698/162671
静态uint SwapEndianness(ulong x)
{
返回(uint)((x&0x000000ff)8)+
((x&0xff000000)>>24));
}
但它不适用于通用windows应用程序,因为Dns和其他相关类不可使用。

选项1 避免这个问题,不要使用互联网时间。相反,使用实时时钟集成电路,如

选择2 使用Windows 10通用应用程序类通过UDP进行连接。它们使用。下面是一些实现数据报套接字并从时间服务器返回响应的粗略代码

private async void ConnectToTimeServer(object sender, RoutedEventArgs e)
{
    var socket = new DatagramSocket();
    socket.MessageReceived += SocketMessageReceived;
    await socket.ConnectAsync(new HostName("time.windows.com"), "123");

    using (var dataWriter = new DataWriter(socket.OutputStream))
    {
        var ntpData = new byte[48];
        ntpData[0] = 0x1B;
        dataWriter.WriteBytes(ntpData);
        await dataWriter.StoreAsync();
    }
}
然后,消息接收到如下事件代码:

private void SocketMessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
{
    try
    {
        using (var reader = args.GetDataReader())
        {
            byte[] response = new byte[48];
            reader.ReadBytes(response);

            YourMethodToParseNetworkTime(response);
        }
    }
    catch (Exception ex)
    {
        // Handle exceptions
    }
}

感谢您的回答。这有助于解决问题。由于某些原因,在互联网上很难找到关于此主题的任何内容。根据我的经验,我推荐DS3231,而不是1302。我发现它更准确,漂移小得多。