配色: 字号:
c# 获取服务器时间
2023-06-25 | 阅:  转:  |  分享 
  
C#获取服务器时间

Posted on 2009-12-16 13:17 Pagan阅读(1052)评论(0)编辑收藏



代码

using System;

using System.Net;

using System.Net.Sockets;



namespace SNTPTime

{

// Leap indicator field values

public enum _LeapIndicator

{

NoWarning,// 0 - No warning

LastMinute61,// 1 - Last minute has 61 seconds

LastMinute59,// 2 - Last minute has 59 seconds

Alarm // 3 - Alarm condition (clock not synchronized)

}



//Mode field values

public enum _Mode

{

SymmetricActive,// 1 - Symmetric active

SymmetricPassive,// 2 - Symmetric pasive

Client, // 3 - Client

Server, // 4 - Server

Broadcast, // 5 - Broadcast

Unknown // 0, 6, 7 - Reserved

}



// Stratum field values

public enum _Stratum

{

Unspecified, // 0 - unspecified or unavailable

PrimaryReference,// 1 - primary reference (e.g. radio-cloc

k)

SecondaryReference,// 2-15 - secondary reference (via NTP

or SNTP)

Reserved // 16-255 - reserved

}



///

/// SNTPTimeClient的摘要说明。

///

/// Public class members:

///

/// LeapIndicator - Warns of an impending leap second to be inse

rted/deleted in the last

/// minute of the current day. (See the _LeapIndicator enum)

///

/// VersionNumber - Version number of the protocol (3 or 4).

///

/// Mode - Returns mode. (See the _Mode enum)

///

/// Stratum - Stratum of the clock. (See the _Stratum enum)

///

/// PollInterval - Maximum interval between successive messages.

///

/// Precision - Precision of the clock.

///

/// RootDelay - Round trip time to the primary reference source.

///

/// RootDispersion - Nominal error relative to the primary refe

rence source.

///

/// ReferenceID - Reference identifier (either a 4 character st

ring or an IP address).

///

/// ReferenceTimestamp - The time at which the clock was last se

t or corrected.

///

/// OriginateTimestamp - The time at which the request departed

the client for the server.

///

/// ReceiveTimestamp - The time at which the request arrived at

the server.

///

/// Transmit Timestamp - The time at which the reply departed th

e server for client.

///

/// RoundTripDelay - The time between the departure of request a

nd arrival of reply.

///

/// LocalClockOffset - The offset of the local clock relative to

the primary reference

/// source.

///

/// Initialize - Sets up data structure and prepares for connect

ion.

///

/// Connect - Connects to the time server and populates the data

structure.

///

/// IsResponseValid - Returns true if received data is valid and

if comes from

/// a NTP-compliant time server.

///

/// ToString - Returns a string representation of the object.

///

/// ----------------------------------------------------------

-------------------

/// Structure of the standard NTP header (as described in RFC 20

30)

/// 1 2 3

/// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0

1

/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

-+-+-+-+

/// |LI | VN |Mode | Stratum | Poll | Precision

|

/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

-+-+-+-+

/// | Root Delay |

/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

-+-+-+-+

/// | Root Dispersion |

/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

-+-+-+-+

/// | Reference Identifier |

/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

-+-+-+-+

/// | |

/// | Reference Timestamp (64)

|

/// | |

/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

-+-+-+-+

/// | |

/// | Originate Timestamp (64)

|

/// | |

/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

-+-+-+-+

/// | |

/// | Receive Timestamp (64) |

/// | |

/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

-+-+-+-+

/// | |

/// | Transmit Timestamp (64)

|

/// | |

/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

-+-+-+-+

/// | Key Identifier (optional) (32)

|

/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

-+-+-+-+

/// | |

/// | |

/// | Message Digest (optional) (128)

|

/// | |

/// | |

/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

-+-+-+-+

///

/// ----------------------------------------------------------

-------------------

///

/// NTP Timestamp Format (as described in RFC 2030)

/// 1 2 3

/// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9

0 1

/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-

+-+-+-+

/// | Seconds |

/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-

+-+-+-+

/// | Seconds Fraction (0-padded) |

/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-

+-+-+-+

///

///


public class SNTPTimeClient

{

// NTP Data Structure Length

private const byte NTPDataLength = 48;

// NTP Data Structure (as described in RFC 2030)

byte[] NTPData = new byte[NTPDataLength];



// Offset constants for timestamps in the data structure

private const byte offReferenceID = 12;

private const byte offReferenceTimestamp = 16;

private const byte offOriginateTimestamp = 24;

private const byte offReceiveTimestamp = 32;

private const byte offTransmitTimestamp = 40;



// Leap Indicator

public _LeapIndicator LeapIndicator

{

get

{

// Isolate the two most significant bits

byte val = (byte)(NTPData[0] >> 6);

switch (val)

{

case 0: return _LeapIndicator.NoWarning;

case 1: return _LeapIndicator.LastMinute61;

case 2: return _LeapIndicator.LastMinute59;

case 3:

default:

return _LeapIndicator.Alarm;

}

}

}



// Version Number

public byte VersionNumber

{

get

{

// Isolate bits 3 - 5

byte val = (byte)((NTPData[0] & 0x38) >> 3);

return val;

}

}



// Mode

public _Mode Mode

{

get

{

// Isolate bits 0 - 3

byte val = (byte)(NTPData[0] & 0x7);

switch (val)

{

case 0:

case 6:

case 7:

default:

return _Mode.Unknown;

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;

}

}

}



// Stratum

public _Stratum Stratum

{

get

{

byte val = (byte)NTPData[1];

if (val == 0) return _Stratum.Unspecified;

else

if (val == 1) return _Stratum.PrimaryReference;

else

if (val <= 15) return _Stratum.SecondaryRefere

nce;

else

return _Stratum.Reserved;

}

}



// Poll Interval

public uint PollInterval

{

get

{

return (uint)Math.Round(Math.Pow(2, NTPData[2]));

}

}



// Precision (in milliseconds)

public double Precision

{

get

{

return (1000 Math.Pow(2, NTPData[3]));

}

}



// Root Delay (in milliseconds)

public double RootDelay

{

get

{

int temp = 0;

temp =256 (256 (256 NTPData[4] + NTPData[5]) +

NTPData[6]) + NTPData[7];

return 1000 (((double)temp) / 0x10000);

}

}



// Root Dispersion (in milliseconds)

public double RootDispersion

{

get

{

int temp = 0;

temp =256 (256 (256 NTPData[8] + NTPData[9]) +

NTPData[10]) + NTPData[11];

return 1000 (((double)temp) / 0x10000);

}

}



// Reference Identifier

public string ReferenceID

{

get

{

string val = "";

switch (Stratum)

{

case _Stratum.Unspecified:

case _Stratum.PrimaryReference:

val += Convert.ToChar(NTPData[offReferenceID +

0]);

val += Convert.ToChar(NTPData[offReferenceID +

1]);

val += Convert.ToChar(NTPData[offReferenceID +

2]);

val += Convert.ToChar(NTPData[offReferenceID +

3]);

break;

case _Stratum.SecondaryReference:

//// switch(VersionNumber)

//// {

//// case 3: // Version 3, Reference ID is

an IPv4 address

//// string Address = NTPData[offReferenc

eID + 0].ToString() + "." +

//// NTPData[offReferenceID + 1].ToStrin

g() + "." +

//// NTPData[offReferenceID + 2].ToStrin

g() + "." +

//// NTPData[offReferenceID + 3].ToStrin

g();

//// try

//// {

//// IPAddress RefAddr = new IPAddress(A

ddress);

//// IPHostEntry Host = DNS.GetHostByAdd

r(RefAddr);

//// 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(GetMilli

Seconds(offReferenceID));

//// // Take care of the time zone

//// long offset = TimeZone.CurrentTimeZo

ne.GetUTCOffset(DateTime.Now);

//// TimeSpan offspan = TimeSpan.FromTick

s(offset);

//// val = (time + offspan).ToString();

//// break;

//// default:

//// val = "N/A";

//// }

break;

}



return val;

}

}



// Reference Timestamp

public DateTime ReferenceTimestamp

{

get

{

DateTime time = ComputeDate(GetMilliSeconds(offRefere

nceTimestamp));

// Take care of the time zone

long offset = Convert.ToInt64(TimeZone.CurrentTimeZon

e.GetUtcOffset(DateTime.Now));

TimeSpan offspan = TimeSpan.FromTicks(offset);

return time + offspan;

}

}



// Originate Timestamp

public DateTime OriginateTimestamp

{

get

{

return ComputeDate(GetMilliSeconds(offOriginateTimes

tamp));

}

}



// Receive Timestamp

public DateTime ReceiveTimestamp

{

get

{

DateTime time = ComputeDate(GetMilliSeconds(offReceiv

eTimestamp));

// Take care of the time zone

long offset = TimeZone.CurrentTimeZone.GetUtcOffset(D

ateTime.Now).Ticks;

TimeSpan offspan = TimeSpan.FromTicks(offset);

return time + offspan;

}

}



// Transmit Timestamp

public DateTime TransmitTimestamp

{

get

{

DateTime time = ComputeDate(GetMilliSeconds(offTransm

itTimestamp));

// Take care of the time zone

long offset = TimeZone.CurrentTimeZone.GetUtcOffset(D

ateTime.Now).Ticks;

TimeSpan offspan = TimeSpan.FromTicks(offset);

return time + offspan;

}

set

{

SetDate(offTransmitTimestamp, value);

}

}



// Reception Timestamp

public DateTime ReceptionTimestamp;



// Round trip delay (in milliseconds)

public int RoundTripDelay

{

get

{

TimeSpan span = (ReceiveTimestamp - OriginateTimestam

p) + (ReceptionTimestamp - TransmitTimestamp);

return (int)span.TotalMilliseconds;

}

}



// Local clock offset (in milliseconds)

public int LocalClockOffset

{

get

{

TimeSpan span = (ReceiveTimestamp - OriginateTimestam

p) - (ReceptionTimestamp - TransmitTimestamp);

return (int)(span.TotalMilliseconds / 2);

}

}



// Compute date, given the number of milliseconds since Janu

ary 1, 1900

private DateTime ComputeDate(ulong milliseconds)

{

TimeSpan span = TimeSpan.FromMilliseconds((double)millis

econds);

DateTime time =new DateTime(1900, 1, 1);

time += span;

return time;

}



// Compute the number of milliseconds, given the offset of a

8-byte array

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;

}



// Compute the 8-byte array, given the date

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).Tota

lMilliseconds;

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;

}

}



// Initialize the NTPClient data

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;

}



// Connect to the time server

public void Connect()

{

try

{

IPAddress hostadd = IPAddress.Parse(TimeServer);

IPEndPoint EPhost =new IPEndPoint(hostadd, Convert.T

oInt32(TimePort));



UdpClient TimeSocket =new UdpClient();

TimeSocket.Connect(EPhost);

Initialize();

TimeSocket.Send(NTPData, NTPData.Length);

NTPData = TimeSocket.Receive(ref EPhost);

if (!IsResponseValid())

{

throw new Exception("Invalid response from " + Tim

eServer);

}

ReceptionTimestamp = DateTime.Now;

}

catch (SocketException e)

{

throw new Exception(e.Message);

}

}



// Check if the response from server is valid

public bool IsResponseValid()

{

if (NTPData.Length < NTPDataLength || Mode != _Mode.Serve

r)

{

return false;

}

else

{

return true;

}

}



// Converts the object to string

public override string ToString()

{

string str;



str ="Leap Indicator: ";

switch (LeapIndicator)

{

case _LeapIndicator.NoWarning:

str +="No warning";

break;

case _LeapIndicator.LastMinute61:

str +="Last minute has 61 seconds";

break;

case _LeapIndicator.LastMinute59:

str +="Last minute has 59 seconds";

break;

case _LeapIndicator.Alarm:

str +="Alarm Condition (clock not synchronized)";

break;

}

str +="\r\nVersion number: " + VersionNumber.ToString()

+ "\r\n";

str +="Mode: ";

switch (Mode)

{

case _Mode.Unknown:

str +="Unknown";

break;

case _Mode.SymmetricActive:

str +="Symmetric Active";

break;

case _Mode.SymmetricPassive:

str +="Symmetric Pasive";

break;

case _Mode.Client:

str +="Client";

break;

case _Mode.Server:

str +="Server";

break;

case _Mode.Broadcast:

str +="Broadcast";

break;

}

str +="\r\nStratum: ";

switch (Stratum)

{

case _Stratum.Unspecified:

case _Stratum.Reserved:

str +="Unspecified";

break;

case _Stratum.PrimaryReference:

str +="Primary Reference";

break;

case _Stratum.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.ToSt

ring() + " ms";

str +="\r\n";



return str;

}



// The URL of the time server we''re connecting to

private string TimeServer;

private string TimePort;



public SNTPTimeClient(string host, string port)

{

TimeServer = host;

TimePort = port;

}

}

}

调用:

SNTPTime.SNTPTimeClient client =new SNTPTime.SNTPTimeCl

ient("210.72.145.44", "123");

client.Connect();



献花(0)
+1
(本文系考试资料文...原创)