উত্তর:
যেহেতু পুরানো স্বীকৃত উত্তর মুছে ফেলা হয়েছে (এটি কোনও গুগল কোড অনুসন্ধানের ফলাফলের লিঙ্ক ছিল যা আর বিদ্যমান নেই), আমি ভেবেছিলাম ভবিষ্যতের রেফারেন্সের জন্য আমি এই প্রশ্নের উত্তর দিতে পারলাম:
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
using(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));
}
দ্রষ্টব্য: আপনাকে নীচের নেমস্পেস যুক্ত করতে হবে
using System.Net;
using System.Net.Sockets;
socket.Receive(ntpData);
) এটি ব্যতিক্রম নিক্ষেপ করা হবে: An existing connection was forcibly closed by the remote host
। তবে সব ঠিক আছে আমি net time
সময় পেতে কমান্ড লাইন ব্যবহার ।
এটি ফাংশনের একটি অনুকূলিত সংস্করণ যা বিটকনভার্টার ফাংশনের উপর নির্ভরতা অপসারণ করে এবং এটি NETMF (। নেট মাইক্রো ফ্রেমওয়ার্ক) এর সাথে সামঞ্জস্যপূর্ণ করে তোলে
public static DateTime GetNetworkTime()
{
const string ntpServer = "pool.ntp.org";
var ntpData = new byte[48];
ntpData[0] = 0x1B; //LeapIndicator = 0 (no warning), VersionNum = 3 (IPv4 only), Mode = 3 (Client Mode)
var addresses = Dns.GetHostEntry(ntpServer).AddressList;
var ipEndPoint = new IPEndPoint(addresses[0], 123);
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.Connect(ipEndPoint);
socket.Send(ntpData);
socket.Receive(ntpData);
socket.Close();
ulong intPart = (ulong)ntpData[40] << 24 | (ulong)ntpData[41] << 16 | (ulong)ntpData[42] << 8 | (ulong)ntpData[43];
ulong fractPart = (ulong)ntpData[44] << 24 | (ulong)ntpData[45] << 16 | (ulong)ntpData[46] << 8 | (ulong)ntpData[47];
var milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000L);
var networkDateTime = (new DateTime(1900, 1, 1)).AddMilliseconds((long)milliseconds);
return networkDateTime;
}
socket.ReceiveTimeout = 3000;
... কোনও নেটওয়ার্ক সমস্যা থাকলে এটি এটি ঝুলন্ত প্রতিরোধ করে। মান মিলিসেকেন্ডে।
কোডপ্লেক্সে পাওয়া নেট নেট মাইক্রো ফ্রেমওয়ার্ক টুলকিটের একটি রয়েছে NTPClient
। আমি নিজে কখনও এটি ব্যবহার করি নি তবে এটি দেখতে ভাল লাগছে।
এখানে আরও একটি উদাহরণ রয়েছে ।
আমি জানি বিষয়টি বেশ পুরানো, তবে এই জাতীয় সরঞ্জামগুলি সর্বদা কার্যকর। আমি উপরের সংস্থানগুলি ব্যবহার করেছি এবং এনটিপিপ্লিনেন্টের এমন একটি সংস্করণ তৈরি করেছি যা ইভেন্ট ভিত্তিক পরিবর্তে অবিচ্ছিন্নভাবে সঠিক সময় অর্জন করতে দেয়।
/// <summary>
/// Represents a client which can obtain accurate time via NTP protocol.
/// </summary>
public class NtpClient
{
private readonly TaskCompletionSource<DateTime> _resultCompletionSource;
/// <summary>
/// Creates a new instance of <see cref="NtpClient"/> class.
/// </summary>
public NtpClient()
{
_resultCompletionSource = new TaskCompletionSource<DateTime>();
}
/// <summary>
/// Gets accurate time using the NTP protocol with default timeout of 45 seconds.
/// </summary>
/// <returns>Network accurate <see cref="DateTime"/> value.</returns>
public async Task<DateTime> GetNetworkTimeAsync()
{
return await GetNetworkTimeAsync(TimeSpan.FromSeconds(45));
}
/// <summary>
/// Gets accurate time using the NTP protocol with default timeout of 45 seconds.
/// </summary>
/// <param name="timeoutMs">Operation timeout in milliseconds.</param>
/// <returns>Network accurate <see cref="DateTime"/> value.</returns>
public async Task<DateTime> GetNetworkTimeAsync(int timeoutMs)
{
return await GetNetworkTimeAsync(TimeSpan.FromMilliseconds(timeoutMs));
}
/// <summary>
/// Gets accurate time using the NTP protocol with default timeout of 45 seconds.
/// </summary>
/// <param name="timeout">Operation timeout.</param>
/// <returns>Network accurate <see cref="DateTime"/> value.</returns>
public async Task<DateTime> GetNetworkTimeAsync(TimeSpan timeout)
{
using (var socket = new DatagramSocket())
using (var ct = new CancellationTokenSource(timeout))
{
ct.Token.Register(() => _resultCompletionSource.TrySetCanceled());
socket.MessageReceived += OnSocketMessageReceived;
//The UDP port number assigned to NTP is 123
await socket.ConnectAsync(new HostName("pool.ntp.org"), "123");
using (var writer = new DataWriter(socket.OutputStream))
{
// NTP message size is 16 bytes of the digest (RFC 2030)
var ntpBuffer = new byte[48];
// Setting the Leap Indicator,
// Version Number and Mode values
// LI = 0 (no warning)
// VN = 3 (IPv4 only)
// Mode = 3 (Client Mode)
ntpBuffer[0] = 0x1B;
writer.WriteBytes(ntpBuffer);
await writer.StoreAsync();
var result = await _resultCompletionSource.Task;
return result;
}
}
}
private void OnSocketMessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
{
try
{
using (var reader = args.GetDataReader())
{
byte[] response = new byte[48];
reader.ReadBytes(response);
_resultCompletionSource.TrySetResult(ParseNetworkTime(response));
}
}
catch (Exception ex)
{
_resultCompletionSource.TrySetException(ex);
}
}
private static DateTime ParseNetworkTime(byte[] rawData)
{
//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(rawData, serverReplyTime);
//Get the seconds fraction
ulong fractPart = BitConverter.ToUInt32(rawData, serverReplyTime + 4);
//Convert From big-endian to little-endian
intPart = SwapEndianness(intPart);
fractPart = SwapEndianness(fractPart);
var milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000L);
//**UTC** time
DateTime networkDateTime = (new DateTime(1900, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).AddMilliseconds((long)milliseconds);
return networkDateTime;
}
// stackoverflow.com/a/3294698/162671
private static uint SwapEndianness(ulong x)
{
return (uint)(((x & 0x000000ff) << 24) +
((x & 0x0000ff00) << 8) +
((x & 0x00ff0000) >> 8) +
((x & 0xff000000) >> 24));
}
}
ব্যবহার:
var ntp = new NtpClient();
var accurateTime = await ntp.GetNetworkTimeAsync(TimeSpan.FromSeconds(10));
ডেটটাইম-টিক্স (মিলিসেকেন্ডের চেয়ে আরও সুনির্দিষ্ট) এর সাথে नेटवर्क সময়গুলি ক্ষতিপূরণ এবং গণনা করার জন্য একটি পরিবর্তিত সংস্করণ
public static DateTime GetNetworkTime()
{
const string NtpServer = "pool.ntp.org";
const int DaysTo1900 = 1900 * 365 + 95; // 95 = offset for leap-years etc.
const long TicksPerSecond = 10000000L;
const long TicksPerDay = 24 * 60 * 60 * TicksPerSecond;
const long TicksTo1900 = DaysTo1900 * TicksPerDay;
var ntpData = new byte[48];
ntpData[0] = 0x1B; // LeapIndicator = 0 (no warning), VersionNum = 3 (IPv4 only), Mode = 3 (Client Mode)
var addresses = Dns.GetHostEntry(NtpServer).AddressList;
var ipEndPoint = new IPEndPoint(addresses[0], 123);
long pingDuration = Stopwatch.GetTimestamp(); // temp access (JIT-Compiler need some time at first call)
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
{
socket.Connect(ipEndPoint);
socket.ReceiveTimeout = 5000;
socket.Send(ntpData);
pingDuration = Stopwatch.GetTimestamp(); // after Send-Method to reduce WinSocket API-Call time
socket.Receive(ntpData);
pingDuration = Stopwatch.GetTimestamp() - pingDuration;
}
long pingTicks = pingDuration * TicksPerSecond / Stopwatch.Frequency;
// optional: display response-time
// Console.WriteLine("{0:N2} ms", new TimeSpan(pingTicks).TotalMilliseconds);
long intPart = (long)ntpData[40] << 24 | (long)ntpData[41] << 16 | (long)ntpData[42] << 8 | ntpData[43];
long fractPart = (long)ntpData[44] << 24 | (long)ntpData[45] << 16 | (long)ntpData[46] << 8 | ntpData[47];
long netTicks = intPart * TicksPerSecond + (fractPart * TicksPerSecond >> 32);
var networkDateTime = new DateTime(TicksTo1900 + netTicks + pingTicks / 2);
return networkDateTime.ToLocalTime(); // without ToLocalTime() = faster
}
http://www.codeproject.com/Articles/237501/Windows-Phone-NTP- ক্লায়েন্ট উইন্ডোজ ফোনের জন্য ভাল কাজ করতে চলেছে।
প্রাসঙ্গিক কোড যুক্ত করা হচ্ছে
/// <summary>
/// Class for acquiring time via Ntp. Useful for applications in which correct world time must be used and the
/// clock on the device isn't "trusted."
/// </summary>
public class NtpClient
{
/// <summary>
/// Contains the time returned from the Ntp request
/// </summary>
public class TimeReceivedEventArgs : EventArgs
{
public DateTime CurrentTime { get; internal set; }
}
/// <summary>
/// Subscribe to this event to receive the time acquired by the NTP requests
/// </summary>
public event EventHandler<TimeReceivedEventArgs> TimeReceived;
protected void OnTimeReceived(DateTime time)
{
if (TimeReceived != null)
{
TimeReceived(this, new TimeReceivedEventArgs() { CurrentTime = time });
}
}
/// <summary>
/// Not reallu used. I put this here so that I had a list of other NTP servers that could be used. I'll integrate this
/// information later and will provide method to allow some one to choose an NTP server.
/// </summary>
public string[] NtpServerList = new string[]
{
"pool.ntp.org ",
"asia.pool.ntp.org",
"europe.pool.ntp.org",
"north-america.pool.ntp.org",
"oceania.pool.ntp.org",
"south-america.pool.ntp.org",
"time-a.nist.gov"
};
string _serverName;
private Socket _socket;
/// <summary>
/// Constructor allowing an NTP server to be specified
/// </summary>
/// <param name="serverName">the name of the NTP server to be used</param>
public NtpClient(string serverName)
{
_serverName = serverName;
}
/// <summary>
///
/// </summary>
public NtpClient()
: this("time-a.nist.gov")
{ }
/// <summary>
/// Begins the network communication required to retrieve the time from the NTP server
/// </summary>
public void RequestTime()
{
byte[] buffer = new byte[48];
buffer[0] = 0x1B;
for (var i = 1; i < buffer.Length; ++i)
buffer[i] = 0;
DnsEndPoint _endPoint = new DnsEndPoint(_serverName, 123);
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
SocketAsyncEventArgs sArgsConnect = new SocketAsyncEventArgs() { RemoteEndPoint = _endPoint };
sArgsConnect.Completed += (o, e) =>
{
if (e.SocketError == SocketError.Success)
{
SocketAsyncEventArgs sArgs = new SocketAsyncEventArgs() { RemoteEndPoint = _endPoint };
sArgs.Completed +=
new EventHandler<SocketAsyncEventArgs>(sArgs_Completed);
sArgs.SetBuffer(buffer, 0, buffer.Length);
sArgs.UserToken = buffer;
_socket.SendAsync(sArgs);
}
};
_socket.ConnectAsync(sArgsConnect);
}
void sArgs_Completed(object sender, SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
byte[] buffer = (byte[])e.Buffer;
SocketAsyncEventArgs sArgs = new SocketAsyncEventArgs();
sArgs.RemoteEndPoint = e.RemoteEndPoint;
sArgs.SetBuffer(buffer, 0, buffer.Length);
sArgs.Completed += (o, a) =>
{
if (a.SocketError == SocketError.Success)
{
byte[] timeData = a.Buffer;
ulong hTime = 0;
ulong lTime = 0;
for (var i = 40; i <= 43; ++i)
hTime = hTime << 8 | buffer[i];
for (var i = 44; i <= 47; ++i)
lTime = lTime << 8 | buffer[i];
ulong milliseconds = (hTime * 1000 + (lTime * 1000) / 0x100000000L);
TimeSpan timeSpan =
TimeSpan.FromTicks((long)milliseconds * TimeSpan.TicksPerMillisecond);
var currentTime = new DateTime(1900, 1, 1) + timeSpan;
OnTimeReceived(currentTime);
}
};
_socket.ReceiveAsync(sArgs);
}
}
}
ব্যবহার:
public partial class MainPage : PhoneApplicationPage
{
private NtpClient _ntpClient;
public MainPage()
{
InitializeComponent();
_ntpClient = new NtpClient();
_ntpClient.TimeReceived += new EventHandler<NtpClient.TimeReceivedEventArgs>(_ntpClient_TimeReceived);
}
void _ntpClient_TimeReceived(object sender, NtpClient.TimeReceivedEventArgs e)
{
this.Dispatcher.BeginInvoke(() =>
{
txtCurrentTime.Text = e.CurrentTime.ToLongTimeString();
txtSystemTime.Text = DateTime.Now.ToUniversalTime().ToLongTimeString();
});
}
private void UpdateTimeButton_Click(object sender, RoutedEventArgs e)
{
_ntpClient.RequestTime();
}
}
Socket
একটি IDisposable
। আপনার এই ক্লাসটিকে মাথায় রেখে আপনার ক্লাসটি ডিজাইন করা উচিত এবং সাধারণ ব্যবহারে এবং যখনই কোনও ব্যতিক্রম উত্থাপিত হয় তখনই সকেটটি ছেড়ে দেওয়ার একটি উপায় সরবরাহ করা উচিত। এই
DateTime.ToLocalTime()