我问这个问题是为了学习目的。
看看我刚刚在wireshark上捕获的这个udp数据包:
(这就是time.windows.com回复以便给我的电脑留出时间)
无论如何,我的问题是关于突出显示的最后8个字节。请注意Wireshark如何正确解析日期。 time.windows.com是如何生成这8个字节的?如何从DateTime.NowUtc
转到wireshark将解析为正确日期的内容?
我试过了:
long dateTime = DateTime.Now.ToFileTimeUtc();
var bytes = BitConverter.GetBytes(dateTime);
但是当我发送那8个字节时,wireshark会将其解析为" 4/15/1998 11:27:52 AM"离开了。
我自1970年以来也尝试过添加毫秒,但仍然显示错误的日期。
以下是有关如何解析响应的示例: http://davidnakoko.com/2013/07/c-get-network-time-from-ntp-server/
但我在哪里可以找到有关如何创建它的示例?
感谢@adjan和@RayFischer回答我提出了一个解决方案。这是:
public static byte[] ConvertToNtp(DateTime datetime)
{
ulong milliseconds = (ulong)((datetime - new DateTime(1900, 1, 1)).TotalMilliseconds);
ulong intpart = 0, fractpart = 0;
var ntpData = new byte[8];
intpart = milliseconds / 1000;
fractpart = ((milliseconds % 1000) * 0x100000000L) / 1000;
//Debug.WriteLine("intpart: " + intpart);
//Debug.WriteLine("fractpart: " + fractpart);
//Debug.WriteLine("milliseconds: " + milliseconds);
var temp = intpart;
for (var i = 3; i >= 0; i--)
{
ntpData[i] = (byte)(temp % 256);
temp = temp / 256;
}
temp = fractpart;
for (var i = 7; i >= 4; i--)
{
ntpData[i] = (byte)(temp % 256);
temp = temp / 256;
}
return ntpData;
}
答案 0 :(得分:1)
对于所有操作系统,有两个重要的值: 1)'时代' 2)间隔
该纪元描述了该值所代表的时间间隔。要引用MS帮助,DateTime.Ticks"表示自0001年1月1日午夜12:00:00起经过的100纳秒间隔的数量。
但我们并没有关注Windows时间。我们正在查看NTP时间。搜索" NTP消息格式"我发现RFC958表示" NTP时间戳表示为64位定点数,相对于1900年1月1日的0000 UT,以秒为单位。整数部分位于前32位,小数部分位于最后32位"
你如何转换?数学。或者查看此处并进行必要的调整: How to convert NTP time to Unix Epoch time in C language (Linux)
答案 1 :(得分:1)
根据您链接的代码,您有:
UInt64 milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000L);
DateTime networkDateTime = (new DateTime(1900, 1, 1)).AddMilliseconds((long)milliseconds);
所以你看到8字节是自19/1年1月1日以来的毫秒数。因此,要生成这样的时间戳,您可以执行
ulong milliseconds = (ulong)((DateTime.Now() - new DateTime(1900, 1, 1)).TotalMilliseconds);
答案 2 :(得分:0)
.Net提供了将DateTime转换为64位二进制表示并返回DateTime的方法。
DateTime localDate = new DateTime(2010, 3, 14, 2, 30, 0, DateTimeKind.Local);
long binLocal = localDate.ToBinary();
DateTime localDate2 = DateTime.FromBinary(binLocal);
上的MSDN文档