|
That is pretty simple. Read the manual
You need to instantiate the NTPClient class, then "connect" to the server. After that, have a look at how the ToString() method is implemented. Everything is there.
Delta Forth .NET (www.dataman.ro)
World's first Forth compiler for the .NET platform
|
|
|
|
|
Yeah, you are right. But to get server time is to call the method ReceiveTimestamp? I notice that both server and local time are the same. Or any other way to get server time?
|
|
|
|
|
Sorry for misunderstanding. I can manage things right now. Thank alot for your nice class and your reply.
Try
|
|
|
|
|
Hi All,
Can anybody provide me sample code in C++ for changing the client machine time from TIME SERVER?
This is very urgent..
Abhijit
|
|
|
|
|
Just wanted to say thanks for writing this. I think it will come in handy in my current project.
|
|
|
|
|
Firstly let me say that this is an excellent class an extremely useful.
That being said, I am encountering a small problem that hopefully somebody could shed some light on.
If I pass an IP address to the SNTPClient constructor it always returns succesful, even if the IP doesnt exist. As an example:
client = new SNTPClient("172.96.211.41");
client.Connect(true);
Console.Writeline(client.ToString());
Doesnt throw any exceptions and returns this
Leap Indicator: No warning
Version number: 3
Mode: Server
Stratum: Secondary Reference
Local time: 27/05/2005 16:29:39
Precision: 9.5367431640625E-07 s
Poll Interval: 1 s
Reference ID: skylar.fbamedia.co.uk (80.253.108.112)
Root Delay: 34.912109375 ms
Root Dispersion: 90.972900390625 ms
Round Trip Delay: 1 ms
Local Clock Offset: 0 ms
I have to admit, I have no idea where the reference ID is coming from.
If I use a non existant host name (e.g. foobar) it does throw an exception.
post.mode = postmodes.signature;
SELECT everything FROM everywhere WHERE something = something_else;
> 1 Row Returned
> 42
|
|
|
|
|
Hi!
Indeed a good article. Great job. I was searching for this functionality on net for quiet some time (to access a time server, as this is needed in my project).
I downloaded the source code and rebuilt it. But the app. is not running on my system. It throws an SocketException with Message : "No such Host is known" and Error code : 11001.
I tried to change the Time Server URL but with no succcess. The Exception is thrown while resolving the IP Address from URL in the line
IPHostEntry hostadd = Dns.Resolve(TimeServer);
of NTPClient.cs's Connect function.
Later I read about ur latest NTPClient app in the discussion board. But I'm facing the same problem.
I guess problem is that I'm using a proxy Server, and app is not able to bypass it. I tried to search ways to bypass the proxy server but again no success.
I would be really greatful to you if you could help me in solving this problem, as I need this functionality to access the Time Server to get the current time of any given location, for eg. London, France etc.
With Regards
and lots of thanks in advance
Shweta
|
|
|
|
|
Ask the sysadmin to open the port 123 for your machine. The same happens in my office. If I connect to Internet from home, the program works ok.
Delta Forth .NET (www.dataman.ro)
World's first Forth compiler for the .NET platform
|
|
|
|
|
This part of the code :
public double Precision<br />
{<br />
get<br />
{<br />
return (1000 * Math.Pow(2, NTPData[3]));<br />
}<br />
}
is wrong; it assumes the precision given in the received data is an unsigned byte instead of a signed byte which leads to abnormal results.
public double Precision<br />
{<br />
get<br />
{<br />
return (Math.Pow(2, (sbyte)NTPData[3]));<br />
}<br />
}
should work much better
|
|
|
|
|
The issue was already addressed around September 2003, see the latest version at http://www.dataman.ro/sntp. Thanks for reminding me that I need to update the article on CP.
Delta Forth .NET (www.dataman.ro)
World's first Forth compiler for the .NET platform
|
|
|
|
|
I downloaded the source code and rebuilt it with .NET2003. It runs fine on my Win2000 machine but under WinXP Professional, I get the same exception "An existing connection was forcibly closed by the remote host" that somebody else mentioned. It's socket error code 10054 (WSACONNRESET) if that helps. Does anybody know what's going on?
|
|
|
|
|
Check if there's a firewall blocking port 123.
Delta Forth .NET (www.dataman.ro)
World's first Forth compiler for the .NET platform
|
|
|
|
|
This sample doesn't work when we retrieve the time from a W2K machine. If instead of the specified servers, any W2K machne is specified as the server, the application throws an exception "An existing connection was forcibly closed by the remote host". Is there any solution to this?
|
|
|
|
|
The class I wrote is a SNTP client, not a server, such that it will query a SNTP server for the current time and will fetch it to the local machine. You need to connect to time servers around the world which are known to be extremely precise. Unless you do your own experimenting with custom written SNTP servers, there's no use to try to connect to machines in your LAN.
Delta Forth .NET (www.dataman.ro)
World's first Forth compiler for the .NET platform
|
|
|
|
|
Good job at implementing this under C#.
One improvement to make it run under Windows CE would be to PInvoke the correct system dll that contains "SetLocalTime()". Under CE it is found in "coredll.dll" instead of "kernel32.dll".
Therefore there should be a conditional compile for either CE or the PC depending on the platform you are building for:
/*
you must add _WIN32_WCE to your "Conditional Compilation Constants"
in your project settings
*/
#if _WIN32_WCE
[DllImport("coredll.dll")]
static extern bool SetLocalTime(ref SYSTEMTIME time);
#else
[DllImport("kernel32.dll")]
static extern bool SetLocalTime(ref SYSTEMTIME time);
#endif
Thank you for this great class!
-Chris
Got RFID?
www.identecsolutions.com[^]
|
|
|
|
|
Incase, you are still looking for it.
The url for Java implementation of a NTP client by Michel Van den Bergh is http://alpha.luc.ac.be/Research/Algebra/Members/Java/
Cheers,
Kavitha Gopal
|
|
|
|
|
"There is a Java implementation of a NTP client by Michel Van den Bergh, but I don't have the URL anymore. Maybe Michel reads this and will send me a note."
No permissions to access the above URL directly, I found this one that does work:
http://alpha.uhasselt.be/Research/Algebra/Members/Java/INSTALL.html
and then just use the link:
Ntp.zip (http://alpha.uhasselt.be/Research/Algebra/Members/Java/Ntp.zip)
Regards,
Jose
|
|
|
|
|
It would be nice if you could specify a timeout for the server connection. If it can't connect, the program seems to run indefinitely.
|
|
|
|
|
this will be nice any ideas how we can implement this?
|
|
|
|
|
I got the timeout working this way. Modify the "Connect" method to the following snippet, and modifiy the SetSocketOption method call to have whatever timeout (in ms) that you want.
Good Luck!
Josh Norris
Senior Software Developer
Henderson Engineers, Inc.
// Connect to the time server and update system time
public void Connect(bool UpdateSystemTime) {
Socket server = null;
try {
// Resolve server address
IPHostEntry hostadd = Dns.Resolve(TimeServer);
IPEndPoint EPhost = new IPEndPoint(hostadd.AddressList[0], 123);
server = new Socket(AddressFamily.InterNetwork,
SocketType.Dgram, ProtocolType.Udp);
int sockopt = (int) server.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout);
server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 1000);
sockopt = (int) server.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout);
Initialize();
server.SendTo(NTPData, NTPData.Length, SocketFlags.None, EPhost);
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint tmpRemote = (EndPoint) sender;
server.ReceiveFrom(NTPData, ref tmpRemote);
if (!IsResponseValid()) {
throw new Exception("Invalid response from " + TimeServer);
}
ReceptionTimestamp = DateTime.Now;
}
catch (SocketException e) {
throw new Exception(e.Message);
}
finally {
if (server != null) {
server.Close();
}
}
// Update system time
if (UpdateSystemTime) {
SetTime();
}
}
|
|
|
|
|
Really nice works cool here!
|
|
|
|
|
If you want to use the simplified UdpClient class as per the original code, then you can access the timeout property via UdpClient.Client.RecieveTimeout which saves you having to use the more general Socket class.
|
|
|
|
|
Try this:
<br />
public void Connect(bool UpdateSystemTime)<br />
{<br />
Socket s = null;<br />
<br />
using(s) <br />
{<br />
IPHostEntry hostadd = Dns.Resolve(TimeServer);<br />
IPEndPoint EPhost = new IPEndPoint(hostadd.AddressList[0], 123);<br />
<br />
s = new Socket(EPhost.Address.AddressFamily, SocketType.Dgram, ProtocolType.Udp);<br />
<br />
s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 8000);<br />
Initialize();<br />
s.SendTo(NTPData, EPhost);<br />
<br />
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);<br />
EndPoint tempRemoteEP = (EndPoint)sender;<br />
<br />
s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 15000);<br />
s.ReceiveFrom(NTPData, ref tempRemoteEP);<br />
if(!IsResponseValid())<br />
{<br />
throw new Exception("Invalid response from " + TimeServer);<br />
}<br />
<br />
if(UpdateSystemTime)<br />
{<br />
SetTime();<br />
}<br />
}<br />
<br />
}<br />
<br />
|
|
|
|
|
Some of your routines return a time span in milliseconds as a Double value. I'd use the standard TimeSpan instead.
Doing so is easy enough: a 'tick', the unit of time for TimeSpan , is 0.1µs, which makes 10 million ticks per second, compared to the 2^16 or 2^32 in the NTP packet.
Note that both the DateTime and TimeSpan types use an Int64 to store their value.
Jeffrey
Everything should be as simple as possible, but not simpler. -- Albert Einstein
http://www.extremeoptimization.com/
|
|
|
|
|
I cannot for the life of me understand why this excellent suggestion has been so lowly rated?
Elegantly converting between the DateTime structure and the data in the sntp datagram is complicated by the fact that internal storage on my machine (standard wintel box) is little endian whilst the sntp datagram uses big-endian by default. The best I could come up with was to use the BitConverter class and Array.Reverse like so:
static uint Get32Bits(byte[] data, int startIndex)
{
byte[] tmp = new byte[4];
Array.Copy(data, startIndex, tmp, 0, 4);
if (BitConverter.IsLittleEndian)
Array.Reverse(tmp);
return BitConverter.ToUInt32(tmp, 0);
}
Once you extract the 32 bit Uint from the sntp structure you can then apply a simple scale factor as per the original commentators suggestion. This replaces a lot of ugly code imho.
|
|
|
|