📄 ntpclient.cs
字号:
{
IPHostEntry Host = Dns.GetHostEntry(Address);
val = Host.HostName + " (" + Address + ")";
}
catch (Exception)
{
val = "N/A";
}
break;
case 4: // Version 4, Reference ID is the timestamp of last update
DateTime time = ComputeDate(GetMilliSeconds(offReferenceID));
// Take care of the time zone
TimeSpan offspan = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now);
val = (time + offspan).ToString();
break;
default:
val = "N/A";
break;
}
break;
}
return val;
}
}
/// <summary>
/// Gets the reference timestamp.
/// </summary>
public DateTime ReferenceTimestamp
{
get
{
DateTime time = ComputeDate(GetMilliSeconds(offReferenceTimestamp));
// Take care of the time zone
TimeSpan offspan = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now);
return time + offspan;
}
}
/// <summary>
/// Gets the originate timestamp.
/// </summary>
public DateTime OriginateTimestamp
{
get
{
return ComputeDate(GetMilliSeconds(offOriginateTimestamp));
}
}
/// <summary>
/// Gets the recieve timestamp.
/// </summary>
public DateTime ReceiveTimestamp
{
get
{
DateTime time = ComputeDate(GetMilliSeconds(offReceiveTimestamp));
// Take care of the time zone
TimeSpan offspan = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now);
return time + offspan;
}
}
/// <summary>
/// Gets the transmit timestamp.
/// </summary>
public DateTime TransmitTimestamp
{
get
{
DateTime time = ComputeDate(GetMilliSeconds(offTransmitTimestamp));
// Take care of the time zone
TimeSpan offspan = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now);
return time + offspan;
}
set
{
SetDate(offTransmitTimestamp, value);
}
}
/// <summary>
/// The reception timestamp.
/// </summary>
public DateTime ReceptionTimestamp;
/// <summary>
/// Gets the round trip delay in milliseconds.
/// </summary>
public int RoundTripDelay
{
get
{
TimeSpan span = (ReceiveTimestamp - OriginateTimestamp) + (ReceptionTimestamp - TransmitTimestamp);
return (int)span.TotalMilliseconds;
}
}
/// <summary>
/// Gets the local clock offset in milliseconds.
/// </summary>
public int LocalClockOffset
{
get
{
TimeSpan span = (ReceiveTimestamp - OriginateTimestamp) - (ReceptionTimestamp - TransmitTimestamp);
return (int)(span.TotalMilliseconds / 2);
}
}
/// <summary>
/// Compute the date given the number of milliseconds since Janyary 1, 1900.
/// </summary>
/// <param name="milliseconds">The number of milliseconds.</param>
/// <returns>The date.</returns>
private DateTime ComputeDate(ulong milliseconds)
{
TimeSpan span = TimeSpan.FromMilliseconds((double)milliseconds);
DateTime time = new DateTime(1900, 1, 1);
time += span;
return time;
}
/// <summary>
/// Compute the number of milliseconds, given the offset of a 8-byte array
/// </summary>
/// <param name="offset">The offset of an 8-byte array.</param>
/// <returns>The number of milliseconds.</returns>
private ulong GetMilliSeconds(byte offset)
{
ulong intpart = 0, fractpart = 0;
for (int i = 0; i <= 3; i++)
{
intpart = 256 * intpart + NTPData[offset + i];
}
for (int i = 4; i <= 7; i++)
{
fractpart = 256 * fractpart + NTPData[offset + i];
}
ulong milliseconds = intpart * 1000 + (fractpart * 1000) / 0x100000000L;
return milliseconds;
}
/// <summary>
/// Compute the 8-byte array, given the date
/// </summary>
/// <param name="offset">The offset.</param>
/// <param name="date">The date.</param>
private void SetDate(byte offset, DateTime date)
{
ulong intpart = 0, fractpart = 0;
DateTime StartOfCentury = new DateTime(1900, 1, 1, 0, 0, 0); // January 1, 1900 12:00 AM
ulong milliseconds = (ulong)(date - StartOfCentury).TotalMilliseconds;
intpart = milliseconds / 1000;
fractpart = ((milliseconds % 1000) * 0x100000000L) / 1000;
ulong temp = intpart;
for (int i = 3; i >= 0; i--)
{
NTPData[offset + i] = (byte)(temp % 256);
temp = temp / 256;
}
temp = fractpart;
for (int i = 7; i >= 4; i--)
{
NTPData[offset + i] = (byte)(temp % 256);
temp = temp / 256;
}
}
/// <summary>
/// Initialize the NTPClient data.
/// </summary>
private void Initialize()
{
// Set version number to 4 and Mode to 3 (client)
NTPData[0] = 0x1B;
// Initialize all other fields with 0
for (int i = 1; i < 48; i++)
{
NTPData[i] = 0;
}
// Initialize the transmit timestamp
TransmitTimestamp = DateTime.Now;
}
/// <summary>
/// Creates a new NTPClient.
/// </summary>
/// <param name="host">The host of the NTP server.</param>
public NTPClient(string host)
{
TimeServer = host;
}
/// <summary>
/// Connect to the time server and update system time.
/// </summary>
/// <param name="UpdateSystemTime">Whether or not to update the system time.</param>
public void Connect(bool UpdateSystemTime)
{
try
{
// Resolve server address
IPHostEntry hostadd = Dns.GetHostEntry(TimeServer);
IPEndPoint EPhost = new IPEndPoint(hostadd.AddressList[0], 123);
//Connect the time server
UdpClient TimeSocket = new UdpClient();
TimeSocket.Connect(EPhost);
// Initialize data structure
Initialize();
TimeSocket.Send(NTPData, NTPData.Length);
NTPData = TimeSocket.Receive(ref EPhost);
if (!IsResponseValid())
{
throw new Exception("Invalid response from " + TimeServer);
}
ReceptionTimestamp = DateTime.Now;
}
catch (SocketException e)
{
throw new Exception(e.Message);
}
// Update system time
if (UpdateSystemTime)
{
SetTime();
}
}
/// <summary>
/// Check if the response from server is valid
/// </summary>
/// <returns>Whether or not the response is valid.</returns>
public bool IsResponseValid()
{
if (NTPData.Length < NTPDataLength || Mode != Modes.Server)
{
return false;
}
else
{
return true;
}
}
/// <summary>
/// Converts the object to string
/// </summary>
/// <returns>A string.</returns>
public override string ToString()
{
string str;
str = "Leap Indicator: ";
switch (LeapIndicator)
{
case LeapIndicators.NoWarning:
str += "No warning";
break;
case LeapIndicators.LastMinute61:
str += "Last minute has 61 seconds";
break;
case LeapIndicators.LastMinute59:
str += "Last minute has 59 seconds";
break;
case LeapIndicators.Alarm:
str += "Alarm Condition (clock not synchronized)";
break;
}
str += "\r\nVersion number: " + VersionNumber.ToString() + "\r\n";
str += "Mode: ";
switch (Mode)
{
case Modes.Unknown:
str += "Unknown";
break;
case Modes.SymmetricActive:
str += "Symmetric Active";
break;
case Modes.SymmetricPassive:
str += "Symmetric Pasive";
break;
case Modes.Client:
str += "Client";
break;
case Modes.Server:
str += "Server";
break;
case Modes.Broadcast:
str += "Broadcast";
break;
}
str += "\r\nStratum: ";
switch (Stratum)
{
case Stratums.Unspecified:
case Stratums.Reserved:
str += "Unspecified";
break;
case Stratums.PrimaryReference:
str += "Primary Reference";
break;
case Stratums.SecondaryReference:
str += "Secondary Reference";
break;
}
str += "\r\nLocal time: " + TransmitTimestamp.ToString();
str += "\r\nPrecision: " + Precision.ToString() + " ms";
str += "\r\nPoll Interval: " + PollInterval.ToString() + " s";
str += "\r\nReference ID: " + ReferenceID.ToString();
str += "\r\nRoot Dispersion: " + RootDispersion.ToString() + " ms";
str += "\r\nRound Trip Delay: " + RoundTripDelay.ToString() + " ms";
str += "\r\nLocal Clock Offset: " + LocalClockOffset.ToString() + " ms";
str += "\r\n";
return str;
}
// SYSTEMTIME structure used by SetSystemTime
[StructLayoutAttribute(LayoutKind.Sequential)]
private struct SYSTEMTIME
{
public short year;
public short month;
public short dayOfWeek;
public short day;
public short hour;
public short minute;
public short second;
public short milliseconds;
}
[DllImport("kernel32.dll")]
static extern bool SetLocalTime(ref SYSTEMTIME time);
// Set system time according to transmit timestamp
private void SetTime()
{
SYSTEMTIME st;
DateTime trts = TransmitTimestamp;
st.year = (short)trts.Year;
st.month = (short)trts.Month;
st.dayOfWeek = (short)trts.DayOfWeek;
st.day = (short)trts.Day;
st.hour = (short)trts.Hour;
st.minute = (short)trts.Minute;
st.second = (short)trts.Second;
st.milliseconds = (short)trts.Millisecond;
SetLocalTime(ref st);
}
// The URL of the time server we're connecting to
private string TimeServer;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -