Is there any C/C++ library to connect with a remote NTP server?
Would it not be a better solution to just have ntpd running on said system to ensure clock being correct instead of having your software manually issuing a sync and possibly causing issues with other applications not enjoying sudden time jumps, especially backwards.
That being said there is libntp I believe.
I'll drop in more things as Google finds them for me.
sntp client in c++ for time/date
This is a code snippet in linux. Hope this will help. I don't know how to convert it to c++.
* This code will query a ntp server for the local time and display
* it. it is intended to show how to use a NTP server as a time
* source for a simple network connected device.
* This is the C version. The orignal was in Perl
*
* For better clock management see the offical NTP info at:
* http://www.eecis.udel.edu/~ntp/
*
* written by Tim Hogard (thogard@abnormal.com)
* Thu Sep 26 13:35:41 EAST 2002
* Converted to C Fri Feb 21 21:42:49 EAST 2003
* this code is in the public domain.
* it can be found here http://www.abnormal.com/~thogard/ntp/
*
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <time.h>
#include <string.h>
void ntpdate();
int main() {
ntpdate();
return 0;
}
void ntpdate() {
char *hostname="tick.usno.navy.mil";
int portno=123; //NTP is port 123
int maxlen=1024; //check our buffers
int i; // misc var i
unsigned char msg[48]={010,0,0,0,0,0,0,0,0}; // the packet we send
unsigned long buf[maxlen]; // the buffer we get back
//struct in_addr ipaddr; //
struct protoent *proto; //
struct sockaddr_in server_addr;
int s; // socket
int tmit; // the time -- This is a time_t sort of
//use Socket;
//
//#we use the system call to open a UDP socket
//socket(SOCKET, PF_INET, SOCK_DGRAM, getprotobyname("udp")) or die "socket: $!";
proto=getprotobyname("udp");
s=socket(PF_INET, SOCK_DGRAM, proto->p_proto);
if(s) {
perror("asd");
printf("socket=%d\n",s);
}
//
//#convert hostname to ipaddress if needed
//$ipaddr = inet_aton($HOSTNAME);
memset( &server_addr, 0, sizeof( server_addr ));
server_addr.sin_family=AF_INET;
server_addr.sin_addr.s_addr = inet_addr(hostname);
//argv[1] );
//i = inet_aton(hostname,&server_addr.sin_addr);
server_addr.sin_port=htons(portno);
//printf("ipaddr (in hex): %x\n",server_addr.sin_addr);
/*
* build a message. Our message is all zeros except for a one in the
* protocol version field
* msg[] in binary is 00 001 000 00000000
* it should be a total of 48 bytes long
*/
// send the data
printf("sending data..\n");
i=sendto(s,msg,sizeof(msg),0,(struct sockaddr *)&server_addr,sizeof(server_addr));
// get the data back
i=recv(s,buf,sizeof(buf),0);
printf("recvfr: %d\n",i);
//perror("recvfr:");
//We get 12 long words back in Network order
/*
for(i=0;i<12;i++)
printf("%d\t%-8x\n",i,ntohl(buf[i]));
*/
/*
* The high word of transmit time is the 10th word we get back
* tmit is the time in seconds not accounting for network delays which
* should be way less than a second if this is a local NTP server
*/
tmit=ntohl((time_t)buf[10]); //# get transmit time
//printf("tmit=%d\n",tmit);
/*
* Convert time to unix standard time NTP is number of seconds since 0000
* UT on 1 January 1900 unix time is seconds since 0000 UT on 1 January
* 1970 There has been a trend to add a 2 leap seconds every 3 years.
* Leap seconds are only an issue the last second of the month in June and
* December if you don't try to set the clock then it can be ignored but
* this is importaint to people who coordinate times with GPS clock sources.
*/
tmit-= 2208988800U;
//printf("tmit=%d\n",tmit);
/* use unix library function to show me the local time (it takes care
* of timezone issues for both north and south of the equator and places
* that do Summer time/ Daylight savings time.
*/
//#compare to system time
printf("Time: %s",ctime(&tmit));
i=time(0);
//printf("%d-%d=%d\n",i,tmit,i-tmit);
printf("System time is %d seconds off\n",i-tmit);
}
Basic NTP Client in Windows in Visual C++
From Figure 8 of RFC 5905 (will need to scroll down to page 18):
0 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 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
One thing I see in figure 8 is that mode, version, and leap should compose the first byte.
Change mode, version, and leap types from unsigned int
to unsigned char
so your bitwise variables only span 1 byte instead of 4. This will make your NTPMessage size the expected 48 bytes.
like:
struct NTPMessage {
unsigned char mode :3;
unsigned char version :2;
unsigned char leap :2;
...
How do I check whether my system's clock is synchronized to a NTP server?
Linux provides adjtimex
, which also gets used by systemd
. You can check various fields to determine if you're still synchronized. A non-negative return value unequal to TIME_ERROR
might be your forte, although you might use the maxerror
or other fields to check the clock's quality instead.
#include <stdio.h>
#include <sys/timex.h>
int main()
{
struct timex timex_info = {};
timex_info.modes = 0; /* explicitly don't adjust any time parameters */
int ntp_result = ntp_adjtime(&timex_info);
printf("Max error: %9ld (us)\n", timex_info.maxerror);
printf("Estimated error: %9ld (us)\n", timex_info.esterror);
printf("Clock precision: %9ld (us)\n", timex_info.precision);
printf("Jitter: %9ld (%s)\n", timex_info.jitter,
(timex_info.status & STA_NANO) ? "ns" : "us");
printf("Synchronized: %9s\n",
(ntp_result >= 0 && ntp_result != TIME_ERROR) ? "yes" : "no");
return 0;
}
Note that systemd
explicitly ignores the reported result (except for errors) and instead checks that the timex_info.maxerror
value hasn't become more than 16 seconds.
This interface has also been provided since the pre-git times. As such, it's guaranteed to be stable, as it might otherwise break Linux's don't-break-userspace-policy.
Related Topics
Program Can't Find Libgcc_S_Dw2-1.Dll
How to Find Out If a Tuple Contains a Type
Printf Rounding Behavior for Doubles
Multiple Inheritance from Two Derived Classes
Order of Calling Base Class Constructor from Derived Class Initialization List
How to Extract the Mantissa of a Double
Enable a Single Warning in Visual Studio
C++:Friend Declaration 'Declares a Non-Template Function
How to Make Gcc Warn on Passing Too-Wide Types to Functions
Why Statements Cannot Appear at Namespace Scope
Does This Type of Memory Get Allocated on the Heap or the Stack
Most Terse and Reusable Way of Wrapping Template or Overloaded Functions in Function Objects
Performance Tradeoff - When Is Matlab Better/Slower Than C/C++
What's Safe for a C++ Plug-In System
How to Embed Webkit into My C/C++/Win32 Application