NTP命名空间下,还有几个类
[StructLayout(LayoutKind.Sequential)] class NtpTime { UInt32 seconds; UInt32 fraction; static readonly DateTime baseTime = new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc); public static implicit operator DateTime(NtpTime time) { /* rfc1305的ntp时间中,时间是用64bit来表示的,记录的是1900年后的秒数(utc格式) * 高32位是整数部分,低32位是小数部分 */ var milliseconds = (int)(((double)ReverseBytes(time.fraction) / uint.MaxValue) * 1000); return baseTime.AddSeconds(ReverseBytes(time.seconds)).AddMilliseconds(milliseconds).ToLocalTime(); } public static implicit operator NtpTime(DateTime time) { NtpTime ntptime = new NtpTime(); TimeSpan span = DateTime.Now.ToUniversalTime() - baseTime; ntptime.seconds = ReverseBytes((uint)span.TotalSeconds); ntptime.fraction = ReverseBytes((uint)((span.TotalSeconds - ntptime.seconds) * uint.MaxValue)); return ntptime; } // 翻转字节顺序 (32-bit) public static UInt32 ReverseBytes(UInt32 value) { return (value & 0x000000FFU) << 24 | (value & 0x0000FF00U) << 8 | (value & 0x00FF0000U) >> 8 | (value & 0xFF000000U) >> 24; } public DateTime DateTime { get { return this; } } } /// <summary> /// 工作模式 /// </summary> public enum Mode : byte { /// <summary> /// 未定义 /// </summary> Unknown = 0, /// <summary> /// 主动对等体模式 /// </summary> SymmetricActive = 1, /// <summary> /// 被动对等体模式 /// </summary> SymmetricPassive = 2, /// <summary> /// 客户端模式 /// </summary> Client = 3, /// <summary> /// 服务器模式 /// </summary> Server = 4, /// <summary> /// 广播或组播模式 /// </summary> Broadcast = 5, /// <summary> /// 控制报文 /// </summary> Control = 6, /// <summary> /// 预留给内部使用 /// </summary> Reserved = 7 } /// <summary> /// NTP报文 /// </summary> [StructLayout(LayoutKind.Sequential)] class Message { byte header; byte stratum = 1; //系统时钟层数 byte poll = 1; //轮询时间,即两个连续NTP报文之间的时间间隔 byte precision = 1; //系统时钟的精度 UInt32 rootDelay; //本地到主参考时钟源的往返时间 UInt32 rootDispersion; //系统时钟相对于主参考时钟的最大误差 UInt32 referenceIdentifier; //参考时钟源的标识 /// <summary> /// 系统时钟最后一次被设定或更新的时间 /// </summary> public NtpTime ReferenceTimestamp { get; set; } /// <summary> /// 请求报文离开发送端时发送端的本地时间 /// </summary> public NtpTime OriginateTimestamp { get; set; } /// <summary> /// 请求报文到达接收端时接收端的本地时间 /// </summary> public NtpTime ReceiveTimestamp { get; set; } /// <summary> /// 应答报文离开应答者时应答者的本地时间 /// </summary> public NtpTime TransmitTimestamp { get; set; } public Message() { header = 0xDB; } /// <summary> /// 获取跳跃指示器 /// </summary> public LeapIndicator LeapIndicator { get { byte val = (byte)(header >> 6); switch (val) { case 0: return LeapIndicator.NoWarning; case 1: return LeapIndicator.LastMinute61; case 2: return LeapIndicator.LastMinute59; case 3: goto default; default: return LeapIndicator.Alarm; } } set { header = (byte)((header & 127) | (((byte)value & 3)) << 6); } } /// <summary> /// 获取版本号 /// </summary> public byte VersionNumber { get { byte val = (byte)((header & 0x38) >> 3); return val; } set { header = (byte)((header & (255 - 56)) | ((value & 7) << 3)); } } /// <summary> /// 获取工作模式 /// </summary> public Mode Mode { get { byte val = (byte)(header & 0x7); switch (val) { case 0: goto default; case 1: return Mode.SymmetricActive; case 2: return Mode.SymmetricPassive; case 3: return Mode.Client; case 4: return Mode.Server; case 5: return Mode.Broadcast; case 6: return Mode.Control; case 7: return Mode.Reserved; default: return Mode.Unknown; } } set { header = (byte)((header & (255 - 7)) | ((byte)value & 7)); } } /// <summary> /// 获取系统时钟层数 /// </summary> public byte Stratum { get { return this.stratum; } set { this.stratum = value; } } public byte Poll { get { return this.poll; } set { this.poll = value; } } public byte Precision { get { return this.precision; } set { this.precision = value; } } public uint RootDelay { get { return this.rootDelay; } set { this.rootDelay = value; } } public uint RootDispersion { get { return this.rootDispersion; } set { this.rootDispersion = value; } } public uint ReferenceIdentifier { get { return this.referenceIdentifier; } set { this.referenceIdentifier = value; } } } /// <summary> /// 跳跃指示器(警告在当月最后一天的最终时刻插入的迫近闰秒) /// </summary> public enum LeapIndicator : byte { /// <summary> /// No warning /// </summary> NoWarning = 0, LastMinute61 = 1, LastMinute59 = 2, /// <summary> /// 告警状态(时钟未同步) /// </summary> Alarm = 3 }
