⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ntpclient.c

📁 ntpclient是通过网络进行系统时间校准的client端程序。从而使多个终端能够保证时间同步性。
💻 C
📖 第 1 页 / 共 2 页
字号:
	double etime,stime,skew1,skew2;	int freq;#define Data(i) ntohl(((unsigned int *)data)[i])	li      = Data(0) >> 30 & 0x03;	vn      = Data(0) >> 27 & 0x07;	mode    = Data(0) >> 24 & 0x07;	stratum = Data(0) >> 16 & 0xff;	poll    = Data(0) >>  8 & 0xff;	prec    = Data(0)       & 0xff;	if (prec & 0x80) prec|=0xffffff00;	delay   = Data(1);	disp    = Data(2);	refid   = Data(3);	reftime.coarse = Data(4);	reftime.fine   = Data(5);	orgtime.coarse = Data(6);	orgtime.fine   = Data(7);	rectime.coarse = Data(8);	rectime.fine   = Data(9);	xmttime.coarse = Data(10);	xmttime.fine   = Data(11);#undef Data	if (stratum == 0)		return -1;	if (set_clock) {   /* you'd better be root, or ntpclient will crash! */		struct timeval tv_set;		/* it would be even better to subtract half the slop */		tv_set.tv_sec  = xmttime.coarse - JAN_1970;		/* divide xmttime.fine by 4294.967296 */		tv_set.tv_usec = USEC(xmttime.fine);		if (settimeofday(&tv_set,NULL)<0) {			perror("settimeofday");			exit(1);		}		if (debug) {			printf("set time to %lu.%.6lu\n", tv_set.tv_sec, tv_set.tv_usec);		}	}	if (debug) {	printf("LI=%d  VN=%d  Mode=%d  Stratum=%d  Poll=%d  Precision=%d\n",		li, vn, mode, stratum, poll, prec);	printf("Delay=%.1f  Dispersion=%.1f  Refid=%u.%u.%u.%u\n",		sec2u(delay),sec2u(disp),		refid>>24&0xff, refid>>16&0xff, refid>>8&0xff, refid&0xff);	printf("Reference %u.%.10u\n", reftime.coarse, reftime.fine);	printf("Originate %u.%.10u\n", orgtime.coarse, orgtime.fine);	printf("Receive   %u.%.10u\n", rectime.coarse, rectime.fine);	printf("Transmit  %u.%.10u\n", xmttime.coarse, xmttime.fine);	printf("Our recv  %u.%.10u\n", arrival->coarse, arrival->fine);	}	etime=ntpdiff(&orgtime,arrival);	stime=ntpdiff(&rectime,&xmttime);	skew1=ntpdiff(&orgtime,&rectime);	skew2=ntpdiff(&xmttime,arrival);	freq=get_current_freq();	if (debug) {	printf("Total elapsed: %9.2f\n"	       "Server stall:  %9.2f\n"	       "Slop:          %9.2f\n",		etime, stime, etime-stime);	printf("Skew:          %9.2f\n"	       "Frequency:     %9d\n"	       " day   second     elapsed    stall     skew  dispersion  freq\n",		(skew1-skew2)/2, freq);	printf("%d %5d.%.3d  %8.1f %8.1f  %8.1f %8.1f %9d\n",		arrival->coarse/86400+15020, arrival->coarse%86400,		arrival->fine/4294967, etime, stime,		(skew1-skew2)/2, sec2u(disp), freq);	}	fflush(stdout);	if (live) {		int new_freq;		new_freq = contemplate_data(arrival->coarse, (skew1-skew2)/2,			etime+sec2u(disp), freq);		if (!debug && new_freq != freq) set_freq(new_freq);	}	return 0;}void setup_receive(int usd, unsigned int interface, short port){	struct sockaddr_in sa_rcvr;	bzero((char *) &sa_rcvr, sizeof(sa_rcvr));	sa_rcvr.sin_family=AF_INET;	sa_rcvr.sin_addr.s_addr=htonl(interface);	sa_rcvr.sin_port=htons(port);	if(bind(usd,(struct sockaddr *) &sa_rcvr,sizeof(sa_rcvr)) == -1) {		fprintf(stderr,"could not bind to udp port %d\n",port);		perror("bind");		exit(1);	}	listen(usd,3);}void setup_transmit(int usd, char *host){        char hostname[HOSTNAME_MAX_LEN];        char *p_temp, *p_cur;        p_cur = host;        /*The NTP servers' ip address is divided by space*/        do        {            p_temp = p_cur;            while((*p_cur != 0x20) && *p_cur != '\0')                p_cur++;                      /*find the space or the end of string, copy the hostname and connect it */            if((*p_cur == 0x20) || (*p_cur == '\0'))           {               if(p_cur - p_temp > HOSTNAME_MAX_LEN)               {                   printf("The hostname is too long\n");                   p_cur++;                    continue;               }	       memcpy(hostname, p_temp, p_cur - p_temp);               hostname[p_cur - p_temp] = '\0'; 	       host_list[host_count++] = strdup(hostname);           }        }while(*(p_cur++) != '\0');	/* initialize resolv.conf status */	resolv_conf_changed();}void primary_loop(int usd, int num_probes, int interval, int initial_interval){	fd_set fds;	struct sockaddr_in addr;	int i, pack_len, sa_xmit_len, probes_sent, next_interval;	int in_startup = 1, active_polling = 1;	struct timeval to;	if (debug) printf("Listening...\n");	probes_sent=0;	next_interval = initial_interval;	send_packet(usd, 0);	for (;;) {		FD_ZERO(&fds);		FD_SET(usd,&fds);		to.tv_sec = next_interval;		to.tv_usec = 0;		i=select(usd+1,&fds,NULL,NULL,&to);  /* Wait on read or error */		if (i<=0) {			if (i<0&&errno==EINTR) continue;			if (i<0) perror("select");			if (i==0) {				if (probes_sent >= num_probes &&					num_probes != 0) break;				if (in_startup)					next_interval = initial_interval;				else if (active_polling) {					server_failed();					next_interval *= 2;					if (next_interval > interval)						next_interval = interval;				} else {					active_polling = 1;					next_interval = initial_interval;				}				send_packet(usd, !in_startup);				++probes_sent;				if (in_startup && probes_sent >= 10)					in_startup = 0;			}				continue;		}		sa_xmit_len = sizeof(addr);		pack_len=recvfrom(usd,incoming,sizeof(incoming),0,		                  (struct sockaddr *)&addr,&sa_xmit_len);		if (!current_addr || addr.sin_addr.s_addr !=				((struct sockaddr_in *)current_addr->ai_addr)					->sin_addr.s_addr)			continue;		if (pack_len<0) {			perror("recvfrom");			server_failed();		} else if (pack_len>0 && pack_len<sizeof(incoming)){			if (udp_handle(usd,incoming,pack_len,						(struct sockaddr *)&addr,						sa_xmit_len) < 0) {				server_failed();			} else {				in_startup = 0;				active_polling = 0;				next_interval = interval;			}		} else {			printf("Ooops.  pack_len=%d\n",pack_len);			fflush(stdout);		}		if (probes_sent >= num_probes && num_probes != 0) break;	}}void do_replay(void){	char line[100];	int n, day, freq, absolute;	float sec, etime, stime, disp;	double skew, errorbar;	int simulated_freq = 0;	unsigned int last_fake_time = 0;	double fake_delta_time = 0.0;	while (fgets(line,sizeof(line),stdin)) {		n=sscanf(line,"%d %f %f %f %lf %f %d",			&day, &sec, &etime, &stime, &skew, &disp, &freq);		if (n==7) {			fputs(line,stdout);			absolute=(day-15020)*86400+(int)sec;			errorbar=etime+disp;			if (debug) printf("contemplate %u %.1f %.1f %d\n",				absolute,skew,errorbar,freq);			if (last_fake_time==0) simulated_freq=freq;			fake_delta_time += (absolute-last_fake_time)*((double)(freq-simulated_freq))/65536;			if (debug) printf("fake %f %d \n", fake_delta_time, simulated_freq);			skew += fake_delta_time;			freq = simulated_freq;			last_fake_time=absolute;			simulated_freq = contemplate_data(absolute, skew, errorbar, freq);		} else {			fprintf(stderr,"Replay input error\n");			exit(2);		}	}}void usage(char *argv0){	fprintf(stderr,	"Usage: %s [-c count] [-d] -h hostname [-i interval] [-l]\n"	"\t[-I startup_interval] [-p port] [-r] [-s] \n",	argv0);}int main(int argc, char *argv[]) {	int usd;  /* socket */	int c;	/* These parameters are settable from the command line	   the initializations here provide default behavior */	short int udp_local_port=0;   /* default of 0 means kernel chooses */	int cycle_time=43200;         /* seconds */	int initial_cycle_time=3;     /* seconds */	int probe_count=0;            /* default of 0 means loop forever */	/* int debug=0; is a global above */	char *hostname=NULL;          /* must be set */	int replay=0;                 /* replay mode overrides everything */	global_argv = argv;	for (;;) {		c = getopt( argc, argv, "c:" DEBUG_OPTION "h:i:I:lp:rs");		if (c == EOF) break;		switch (c) {			case 'c':				probe_count = atoi(optarg);				break;#ifdef ENABLE_DEBUG			case 'd':				++debug;				break;#endif			case 'h':				hostname = optarg;				break;			case 'i':				cycle_time = atoi(optarg);				/* Don't take out this check unless you are				 * only querying servers that you own. */				if (cycle_time < 3600) {					fprintf(stderr, "Interval of less than "							"3600 is too short.\n");					exit(1);				}				break;			case 'I':				initial_cycle_time = atoi(optarg);				break;			case 'l':				live++;				break;			case 'p':				udp_local_port = atoi(optarg);				break;			case 'r':				replay++;				break;			case 's':				set_clock++;				probe_count = 0;				break;			default:				usage(argv[0]);				exit(1);		}	}#ifdef vxworks	hostname = argv[0];	set_clock++;#endif	if (replay) {		do_replay();		exit(0);	}	if (hostname == NULL) {		usage(argv[0]);		exit(1);	}	if (debug) {		printf("Configuration:\n"		"  -c probe_count %d\n"		"  -d (debug)     %d\n"		"  -h hostname    %s\n"		"  -i interval    %d\n"		"  -I st_interval %d\n"		"  -l live        %d\n"		"  -p local_port  %d\n"		"  -s set_clock   %d\n",		probe_count, debug, hostname, cycle_time, initial_cycle_time,		live, udp_local_port, set_clock );	}	/* Startup sequence */	if ((usd=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))==-1)		{perror ("socket");exit(1);}	fcntl(usd, F_SETFD, FD_CLOEXEC);	setup_receive(usd, INADDR_ANY, udp_local_port);	setup_transmit(usd, hostname);	primary_loop(usd, probe_count, cycle_time, initial_cycle_time);	close(usd);	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -