//effect:send ntp packet and get the ntp packet ,make the time OK
//2014.7.31 is OK
//
#include <sys/types.h>
#include <sys/socket.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <netinet/udp.h>
#include <linux/if_ether.h>
#include <pthread.h>
#include <netdb.h>
#include <stddef.h>

///////////////////something for the ntp control;do by zhb //////////////////////////////////////////////
#define int8 char
#define uint8 unsigned char
#define uint32 unsigned int
#define ulong32 unsigned long
#define long32 long
#define int32 int
#define long64 long long
#define u_int32 unsigned long

#define NTP_PORT 123 /*NTP专用端口号字符串*/
#define TIME_PORT 37 /* TIME/UDP端口号 */
#define NTP_PORT_STR "123" /*NTP专用端口号字符串*/

#define NTP_SERVER_IP "192.168.1.21" /*ntp service IP*/
//3600s*24h*(365days*70years+17days)
#define JAN_1970 0x83aa7e80U // /* 1900年~1970年之间的时间秒数 */
///////////////////////////////////////////////////////////
#define PKT_MODE(li_vn_mode) ((u_char)((li_vn_mode) & 0x7))
#define PKT_VERSION(li_vn_mode) ((u_char)(((li_vn_mode) >> 3) & 0x7))
#define PKT_LEAP(li_vn_mode) ((u_char)(((li_vn_mode) >> 6) & 0x3))

//#define debug 1
struct ntp_packet
{
uint8 li_vn_mode;
uint8 stratum;
uint8 poll;
uint8 precision;
ulong32 root_delay;
ulong32 root_dispersion;
// int8 ref_id[4];
ulong32 ref_id;
ulong32 reftimestamphigh;
ulong32 reftimestamplow;
ulong32 oritimestamphigh;
ulong32 oritimestamplow;
ulong32 recvtimestamphigh;
ulong32 recvtimestamplow;
ulong32 trantimestamphigh;
ulong32 trantimestamplow;
};
long64 firsttimestamp,finaltimestamp;

int sendpkt(int sockfd,struct addrinfo * res)
{

struct ntp_packet ntppack,newpack;

//put the date into the ntppack
ntppack.li_vn_mode = 0x23;
ntppack.stratum = 0x02;
ntppack.poll = 0x04;
ntppack.precision = 0xec;
ntppack.root_delay = htonl(1<<16);//root_delay = 1.0sec
ntppack.root_dispersion = htonl(1<<8);//root_dispersion = 0.0039sec
ntppack.ref_id = inet_addr(NTP_SERVER_IP);
//获取初始时间戳T1
firsttimestamp=JAN_1970+time(NULL);//-8*3600
// printf("%lx,%lx\n",JAN_1970,firsttimestamp);
ntppack.reftimestamphigh = htonl(firsttimestamp);
ntppack.oritimestamphigh = htonl(firsttimestamp);
ntppack.recvtimestamphigh = htonl(firsttimestamp);
ntppack.trantimestamphigh= htonl(firsttimestamp);

int i;
for(i=0; i<1; i++)
{
int ret = sendto(sockfd,&ntppack,sizeof(ntppack),0, res->ai_addr, res->ai_addrlen);
if(ret < 0){
perror("sendto");
return 1;
}
}

}
int getresponse(int sockfd,struct addrinfo * res,struct ntp_packet rpkt)
{
// struct ntp_packet rpkt,newpack;
fd_set pending_data;
struct timeval block_time;
char *refid ;

/*调用select()函数,并设定超时时间为1s*/
FD_ZERO(&pending_data);
FD_SET(sockfd, &pending_data);

block_time.tv_sec=10;//how time to ask
block_time.tv_usec=0;
if (select(sockfd + 1, &pending_data, NULL, NULL, &block_time) > 0)

{
int num;
/*接收服务器端的信息*/
if ((num = recvfrom(sockfd, &rpkt,
sizeof(rpkt), 0, res->ai_addr, &res->ai_addrlen)) < 0)
{
perror("recvfrom");
return 0;
}

/* 设置接收NTP包的数据结构 */
int mode = PKT_MODE(rpkt.li_vn_mode);
int version = PKT_VERSION(rpkt.li_vn_mode);
int leap = PKT_LEAP(rpkt.li_vn_mode);

int stratum = rpkt.stratum;
int poll = rpkt.poll;
int precision = rpkt.precision;

//到达客户机时间戳T4
finaltimestamp=time(NULL)+JAN_1970;//-8*3600;
///将网络上传送的大端数据改为小端形式。
rpkt.root_dispersion= ntohl(rpkt.root_dispersion);
rpkt.reftimestamphigh=ntohl(rpkt.reftimestamphigh);
rpkt.reftimestamplow= ntohl(rpkt.reftimestamplow);
rpkt.oritimestamphigh= ntohl(rpkt.oritimestamphigh);
rpkt.oritimestamplow= ntohl(rpkt.oritimestamplow);
rpkt.recvtimestamphigh= ntohl(rpkt.recvtimestamphigh);
rpkt.recvtimestamplow= ntohl(rpkt.recvtimestamplow);
rpkt.trantimestamphigh= ntohl(rpkt.trantimestamphigh);
rpkt.trantimestamplow= ntohl(rpkt.trantimestamplow);
#ifdef debug
printf("li=%d,version=%d,mode=%d\n",leap,version,mode);
printf("stratum=%d,poll=%d,precision=%d\n",stratum,poll,precision);
printf("################ data ####################\n");
printf("root_delay=%ld\n",rpkt.root_delay);
printf("dispersion=%ld\n",rpkt.root_dispersion);
// printf("Id=%s\n",(*(int*)&rpkt.ref_id));
printf("refh=%lx\n",rpkt.reftimestamphigh);
printf("relw=%lx\n",rpkt.reftimestamplow);
printf("orih=%lx\n",rpkt.oritimestamphigh);
printf("oril=%lx\n",rpkt.oritimestamplow);
printf("rech=%lx\n",rpkt.recvtimestamphigh);
printf("recl=%lx\n",rpkt.recvtimestamplow);
printf("trah=%lx\n",rpkt.trantimestamphigh);
printf("tral=%lx\n",rpkt.trantimestamplow);
#endif

long64 diftime,delaytime;
//求出客户机跟服务器的时间差=((T2-T1)+(T3-T4))/2
diftime=((rpkt.recvtimestamphigh-firsttimestamp)+(rpkt.trantimestamphigh-finaltimestamp))>>1;
//求出延时
delaytime=((rpkt.recvtimestamphigh-firsttimestamp)-(rpkt.trantimestamphigh-finaltimestamp))>>1;
//diftime=(5-9)>>1;

//求出真正时间的时间戳
struct timeval tv1;
tv1.tv_sec=time(NULL)+diftime+delaytime;
tv1.tv_usec=0;
settimeofday(&tv1,NULL);
#ifdef debug
printf("\n\ndebug information ...\n\n");
printf("time(NULL) is %ld\n",time(NULL));
printf("different time is %ld\n",diftime);
printf("delaytime is %ld\n",delaytime);
printf("time(NULL)+diftime+delaytime=%ld\n",time(NULL)+diftime+delaytime);
printf("tv1.tv_sec is %ld\n\n", tv1.tv_sec);
#endif
}
return 1;
}

int main()
{

struct addrinfo *res = NULL,hints;

memset(&hints,0,sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;

/*调用getaddrinfo()函数,获取地址信息*/
int rc = getaddrinfo(NTP_SERVER_IP, NTP_PORT_STR, &hints, &res);
if (rc != 0)
{
perror("getaddrinfo");
return 1;
}

int fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if(fd < 0){
perror("socket");
return 0;
}

sendpkt(fd,res);
int i;

struct ntp_packet rpkt;
i = getresponse(fd,res,rpkt);

printf("time is OK\n");
close(fd);
}

http://www.gpstime.com.cn/chanpin/pinlv/227.html

ntp 校时程序的更多相关文章

  1. GPS北斗NTP校时服务器原理及功能介绍

    在科技的发展下GPS北斗NTP校时服务器也得到了广泛应用,比如工业.科研.航空航天.公共场所等领域都用到了GPS北斗NTP校时服务器,该时间服务器以卫星时间为基准授时准确,替代了传统钟表授时的单一和时 ...

  2. NTP校时设置

    一.Windows Server 2008 – Time Server 前言: 国家时间与频率标准实验室  && NTP服务器 也可以忽略1~6 直接跳7 如果已改过机码请使用 1   ...

  3. Linux NTP校时

    1.安装客户端(root权限运行) apt-get install ntpdate 2.修改配置文件:“/etc/default/ntpdate”,     NTPSERVERS="ntp. ...

  4. 北斗时钟同步系统-GPS卫星授时设备-NTP网络校时服务器

    北斗时钟同步系统-GPS卫星授时设备-NTP网络校时服务器 北斗时钟同步系统-GPS卫星授时设备-NTP网络校时服务器 北斗时钟同步系统-GPS卫星授时设备-NTP网络校时服务器 论述当下网络时间同步 ...

  5. 网络时钟服务器,NTP授时设备,北斗网络校时服务器,GPS时间同步器

    网络时钟服务器,NTP授时设备,北斗网络校时服务器,GPS时间同步器 网络时钟服务器,NTP授时设备,北斗网络校时服务器,GPS时间同步器 论述当下网络时间同步的重要性   北京华人开创科技发展有限公 ...

  6. GPS校时器,GPS时钟装置,NTP网络时间服务器

    GPS校时器,GPS时钟装置,NTP网络时间服务器 GPS校时器,GPS时钟装置,NTP网络时间服务器 GPS校时器,GPS时钟装置,NTP网络时间服务器 GPS校时器,GPS时钟装置,NTP网络时间 ...

  7. 实现基于NTP协议的网络校时功能

    无论PC端还是移动端系统都自带时间同步功能,基于的都是NTP协议,这里使用C#来实现基于NTP协议的网络校时功能(也就是实现时间同步). 1.NTP原理 NTP[Network Time Protoc ...

  8. KNY团队与“易校”小程序介绍

    一.团队介绍 “KNY”团队是软件工程专业中的一支充满了斗志,充满了自信的队伍,由三人组成,每个队员都在为我们共同一致的目标而努力:我们三个人的小程序的知识都相对薄弱,但我们不甘落后,一直在努力的学习 ...

  9. 记一个有想法却没能力实现的硬件产品——mp3校时闹钟

    枕头旁的闹钟,我想大家都用过,很便宜.用一节干电池供电.但其最大的缺点就是不太准,不能校时. 电池啥事用光,也不知道.钟是走的很慢,没按时闹,搞的自己迟了到. 于是就有了我的漫长思考过程... 先说手 ...

随机推荐

  1. 【Loj#535】花火(线段树,扫描线)

    [Loj#535]花火(线段树,扫描线) 题面 Loj 题解 首先如果不考虑交换任意两个数这个操作,答案就是逆序对的个数. 那么暴力就是枚举交换哪个两个数,然后用数据结构之类的东西动态维护逆序对. 但 ...

  2. unity3d点击屏幕选中物体

    原文  http://blog.csdn.net/mycwq/article/details/19906335 前些天接触unity3d,想实现点击屏幕选中物体的功能.后来研究了下,实现原理就是检测从 ...

  3. 20135239益西拉姆 Linux内核分析 操作系统是怎样工作的?

    益西拉姆+ 原创作品+ <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 ” 堆栈 堆栈是C语言程序运行时 ...

  4. POJ 3171 DP

    Cleaning Shifts Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3563   Accepted: 1205 D ...

  5. HDU 6034 贪心

    Balala Power! Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

  6. html5的web存储详解

    以前我们在本地存储数据都是用document.cookie来存储的,但是由于其的存储大小只有4K左右,解析也很复杂,给开发带来了诸多的不便.不过现在html5出了web的存储,弥补了cookie的不足 ...

  7. Codeforces 797 D. Broken BST

    D. Broken BST http://codeforces.com/problemset/problem/797/D time limit per test 1 second memory lim ...

  8. errno错误号含义

    errno0 : Success errno1 : Operation not permitted errno2 : No such file or directory errno3 : No suc ...

  9. .net core 集成 autofac.

    1. Install Install-Package Autofac Install-Package Autofac.Extensions.DependencyInjection 2.Startup ...

  10. javascript在IE下不能用 trim函数解决方法

    javascript 的trim 函数在firefox 下面使用没有问题 <script language="javascript"> var test1 = &quo ...