打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Linux NTP协议
int8     char
#define uint8    unsigned char
#define uint32   unsigned int
#define ulong32   unsigned long
#define long32   long
#define int32    int
#define long64    longlong

#define  debug

//3600s*24h*(365days*70years+17days)
#define  From00to70 0x83aa7e80U

#define  NTPSVR1 "132.163.4.102"       //USA
#define  NTPSVR2 "132.163.135.132"     //USA
#define  NTPSVR3 "192.53.103.103"      //Germany

#define  NTPPORT  123
typedef struct NTPPACKET
{
 uint8    li_vn_mode;
 uint8    stratum;
 uint8    poll;
 uint8    precision;
  ulong32  root_delay;
  ulong32  root_dispersion;
 int8     ref_id[4];
  ulong32  reftimestamphigh;
  ulong32  reftimestamplow;
  ulong32  oritimestamphigh;
  ulong32  oritimestamplow;
  ulong32  recvtimestamphigh;
  ulong32  recvtimestamplow;
  ulong32  trantimestamphigh;  
  ulong32  trantimestamplow;
}NTPPacket;

NTPPacket  ntppack,newpack;

//定义为long64,解决32位数的符号位问题
long64  firsttimestamp,finaltimestamp;
long64   diftime,delaytime;

void NTP_Init()
{
 bzero(&ntppack,sizeof(ntppack));
 ntppack.li_vn_mode=0x1b;//0|(3<<2)|(3<<5);
  //获取初始时间戳T1
 firsttimestamp="From00to70"+time(NULL);//-8*3600;
 ntppack.oritimestamphigh=htonl(firsttimestamp);
}
int main()
{

//  ulong32 clienttime;
//  ulong32diftime,firsttimestamp,finaltimestamp;
  fd_set  inset1;
  int32  sockfd;
  struct tim tv,tv1;
  struct timezone tz;
  struct sockaddr_in addr;
//printf("%d,%d,%d/n",&ntppack.li_vn_mode,&ntppack.stratum,&ntppack.poll);
// printf("%d %ld/n",sizeof(NTPPacket),sizeof(ntppack));
 
//  printf("%ld/n",time(NULL));
 
 if((sockfd=socket(AF_INET,SOCK_DGRAM,0))<0)
    {
     perror("create socket error!/n");
     exit(1);
    }
 
 addr.sin_family=AF_INET;  //IPV4协议
  addr.sin_port=htons(NTPPORT);  //NTP专用的123端口
 addr.sin_addr.s_addr=inet_addr(NTPSVR1);  //校时服务器
 bzero(&(addr.sin_zero),8);  //清零
 
  //wait 5s
 tv.tv_sec=10;   //select等待时间为10S
  tv.tv_usec=0;
 
  FD_ZERO(&inset1);
  FD_SET(sockfd,&inset1);
 
  NTP_Init();
  //发送数据请求包
 sendto(sockfd,&ntppack,sizeof(ntppack),0,(structsockaddr *)&addr,sizeof(struct sockaddr));
  //select巡视
 if(select(sockfd+1,&inset1,NULL,NULL,&tv)<0)
  {
   perror("select error!/n");
   exit(1);
  }
  else
  {
  //printf("OK/n");
   if(FD_ISSET(sockfd,&inset1))
    {
  // printf("OK/n");
    if(recv(sockfd,&newpack,sizeof(newpack),0)<0)       //接收数据在newpack中。
    {
     perror("recv error!/n");
     exit(1);
    }
    }
  }
  //到达客户机时间戳T4
 finaltimestamp=time(NULL)+From00to70;//-8*3600;
 
  //将网络上传送的大端数据改为小端形式。
 newpack.root_delay=ntohl(newpack.root_delay);
 newpack.root_dispersion=ntohl(newpack.root_dispersion);
 newpack.reftimestamphigh=ntohl(newpack.reftimestamphigh);
 newpack.reftimestamplow=ntohl(newpack.reftimestamplow);
 newpack.oritimestamphigh=ntohl(newpack.oritimestamphigh);
 newpack.oritimestamplow=ntohl(newpack.oritimestamplow);
 newpack.recvtimestamphigh=ntohl(newpack.recvtimestamphigh);
 newpack.recvtimestamplow=ntohl(newpack.recvtimestamplow);
 newpack.trantimestamphigh=ntohl(newpack.trantimestamphigh);
 newpack.trantimestamplow=ntohl(newpack.trantimestamplow);
 
 //求出客户机跟服务器的时间差=((T2-T1)+(T3-T4))/2
 diftime=((newpack.recvtimestamphigh-firsttimestamp)+(newpack.trantimestamphigh-finaltimestamp))>>1;
 //求出延时
 delaytime=((newpack.recvtimestamphigh-firsttimestamp)-(newpack.trantimestamphigh-finaltimestamp))>>1;
 //diftime=(5-9)>>1;

 //求出真正时间的时间戳
 tv1.tv_sec=time(NULL)+diftime+delaytime;
 tv1.tv_usec=0;
 //tz.

 #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
 
  settimeofday(&tv1,NULL);
//diftime=diftime-From00to70;

 #ifdef debug
  //printf("different time is%ld/n",diftime);
  printf("delay  time is%ld/n",delaytime);
  //printf("firsttimestamp is%x/n",time(NULL));
  printf("newpack.tran is%ld/n",newpack.trantimestamphigh);
  printf("newpack.recv is%ld/n",newpack.recvtimestamphigh);
  printf("firsttimestamp is%ld/n",firsttimestamp);
  printf("finaltimestamp is%ld/n",finaltimestamp);
  printf("newpack.recv-firsttimestamp is%ld/n",newpack.recvtimestamphigh-firsttimestamp);
  printf("newpack.tran-finaltimestamp is%ld/n",newpack.trantimestamphigh-finaltimestamp);
  printf("(recv-first)+(ftran-final) is%ld/n",(newpack.recvtimestamphigh-firsttimestamp)+(newpack.trantimestamphigh-finaltimestamp));
 printf("((recv-first)+(ftran-final))>>1is%ld/n",((newpack.recvtimestamphigh-firsttimestamp)+(newpack.trantimestamphigh-finaltimestamp))>>1);
  printf("different time is%ld/n/n",diftime);
  printf("sizeof(long long) is:%d/n",sizeof(long long));
  printf("Current time is.../n");
  system("date");
 #endif
}
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
NTP校时客户端
通过API访问设备驱动程序
c
C++ 实现ping功能和域名(URL)解析实际IP地址
探测Windows2K/XP/2003本机系统信息
实战DeviceIoControl 之一:通过API访问设备驱动程序 - bhw98的专栏...
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服