Is there any C/C++ library to connect with a remote NTP server? [closed]
Asked Answered
E

2

6

I'm making a C++ software that needs to syncronize system clock with remote NTP server. For now, I'm ussing "system" command to call the console "ntpdate" command.

..But I think is an ugly way to do that.

Do you know any library that let me connect to remote NTP server? Thanks.

Eades answered 17/2, 2012 at 10:35 Comment(2)
Surely a better way is just to install the ntpd daemon, which will keep your system's clock synchronised all the time?Perspiration
See also https://mcmap.net/q/1770053/-how-do-i-check-whether-my-system-39-s-clock-is-synchronized-to-a-ntp-server for a Linux-specific Q&A.Vonvona
Z
6

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.

Zootomy answered 17/2, 2012 at 10:42 Comment(6)
+1 for ntpd and the phrase sudden time jumps. BACK TO THE FUTURE!Perspiration
@Li-aungYip, yep, having manually used ntpdate I have had all sorts of processes fail when files are from the future.Zootomy
The most fun (user visible) one I've had is that jumping the clock causes KDE's compositing window manager to freak out and die. Apparently kwm keeps track of its performance with a timestamp since the last frame was rendered, the intent being to turn off compositing if things get too slow. Jumping the clock forwards 10 seconds makes it think it's only getting 0.1 FPS and triggers kwms death. ;)Perspiration
That does sound fun and probably how it is solved, maybe need to try nagging some kwin dev about how good an idea that was. Naah they just tell me to fix it and send a patch no fun there.Zootomy
yes, ntpd seems to be the rigth way :). Thanks for the advice and for the funny comments.Septal
You may want to look at ntpclient code on github: github.com/lettier/ntpclient/blob/master/source/c/main.c also there is documentation related to this on: lettier.github.io/posts/…Pontius
I
8

this works in c++ (adapted from c). it will get you UTC time from pool.ntp.br (you MUST use IP). if you manage to work out how to get DAYTIME (daylight savings - horario verao), please advise. i can get it from UFRJ pads servers, but UFRJ is unreliable, what with them being on strike half the year...

/* 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 ([email protected])
 * 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>
#include <iostream>

void ntpdate();

int main() {
    ntpdate();
    return 0;
}

void ntpdate() {
//char *hostname=(char *)"163.117.202.33";
//char *hostname=(char *)"pool.ntp.br";
char    *hostname=(char *)"200.20.186.76";
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
long 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);
perror("socket");
//
//#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));
perror("sendto");
// get the data back
struct sockaddr saddr;
socklen_t saddr_l = sizeof (saddr);
i=recvfrom(s,buf,48,0,&saddr,&saddr_l);
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]));
    long tmit2=ntohl((time_t)buf[i]);
    std::cout << "Round number " << i << " time is " << ctime(&tmit2)  << std::endl;
}
*/
/*
 * 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
tmit=ntohl((time_t)buf[4]);    //# 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));

std::cout << "time is " << ctime(&tmit)  << std::endl;
i=time(0);
//printf("%d-%d=%d\n",i,tmit,i-tmit);
//printf("System time is %d seconds off\n",(i-tmit));
std::cout << "System time is " << (i-tmit) << " seconds off" << std::endl;
}
Independency answered 7/11, 2013 at 11:55 Comment(1)
NTPClient is an elegant alternative for Windows using the boost libraries (make sure to compile and add the paths). As discussed here, ntp.flags.mode in unsigned char msg[48]={010,0,0,0,0,0,0,0,0} and the buffer extraction position in tmit=ntohl((time_t)buf[4]); may have to be changed according to your goals.Marchetti
Z
6

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.

Zootomy answered 17/2, 2012 at 10:42 Comment(6)
+1 for ntpd and the phrase sudden time jumps. BACK TO THE FUTURE!Perspiration
@Li-aungYip, yep, having manually used ntpdate I have had all sorts of processes fail when files are from the future.Zootomy
The most fun (user visible) one I've had is that jumping the clock causes KDE's compositing window manager to freak out and die. Apparently kwm keeps track of its performance with a timestamp since the last frame was rendered, the intent being to turn off compositing if things get too slow. Jumping the clock forwards 10 seconds makes it think it's only getting 0.1 FPS and triggers kwms death. ;)Perspiration
That does sound fun and probably how it is solved, maybe need to try nagging some kwin dev about how good an idea that was. Naah they just tell me to fix it and send a patch no fun there.Zootomy
yes, ntpd seems to be the rigth way :). Thanks for the advice and for the funny comments.Septal
You may want to look at ntpclient code on github: github.com/lettier/ntpclient/blob/master/source/c/main.c also there is documentation related to this on: lettier.github.io/posts/…Pontius

© 2022 - 2024 — McMap. All rights reserved.