zoukankan      html  css  js  c++  java
  • C实现一个NTP客户端,可以从指定IP的NTP服务器获取时间戳

    参考::https://blog.csdn.net/dosthing/article/details/81588219

    下面的代码测试通过

    头文件

    #include <sys/types.h>  
    #include <sys/stat.h> 
    #include <sys/ioctl.h> 
    #include <sys/socket.h>
    #include <sys/wait.h> 
    #include <sys/time.h>
    #include <netdb.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h> 
    #include <stdio.h>  
    #include <stdlib.h>
    #include <string.h>  
    #include <pthread.h>   
    #include <dirent.h> 
    #include <time.h>
    #include <fcntl.h> 
    #include <errno.h>
     
    #define debugprintf 1
    #ifdef debugprintf
        #define debugpri(mesg, args...) fprintf(stderr, "[NetRate print:%s:%d:] " mesg "
    ", __FILE__, __LINE__, ##args) 
    #else
        #define debugpri(mesg, args...)
    #endif
     
    #define JAN_1970             0x83aa7e80
    #define NTPFRAC(x) (4294 * (x) + ((1981 * (x))>>11))
    #define USEC(x) (((x) >> 12) - 759 * ((((x) >> 10) + 32768) >> 16))
    #define Data(i) ntohl(((unsigned int *)data)[i])
    #define LI 0
    #define VN 3
    #define MODE 3
    #define STRATUM 0
    #define POLL 4 
    #define PREC -6
    
    
    struct NtpTime 
    {
        unsigned int coarse;
        unsigned int fine;
    };
    
    void sendPacket(int fd);
    void getNewTime(unsigned int *data,struct timeval *ptimeval);
    double getNtpTime(char * pIP);

    源文件

    #include "ntp1_so.h"

     int main()
     {
      char myIP[20]="52.175.49.4"; //time.windows.com
      double currentTime = getNtpTime(myIP);
      printf("currentTime=%f ",currentTime);

      return 0;
     }


    void sendPacket(int fd) { unsigned int data[12]; struct timeval now; if (sizeof(data) != 48) { fprintf(stderr,"size error "); return; } memset((char*)data, 0, sizeof(data)); data[0] = htonl((LI << 30) | (VN << 27) | (MODE << 24) | (STRATUM << 16) | (POLL << 8) | (PREC & 0xff)); data[1] = htonl(1<<16); data[2] = htonl(1<<16); gettimeofday(&now, NULL); data[10] = htonl(now.tv_sec + JAN_1970); data[11] = htonl(NTPFRAC(now.tv_usec)); send(fd, data, 48, 0); } void getNewTime(unsigned int *data,struct timeval *ptimeval) { struct NtpTime trantime; trantime.coarse = Data(10); trantime.fine = Data(11); ptimeval->tv_sec = trantime.coarse - JAN_1970; ptimeval->tv_usec = USEC(trantime.fine); } double getNtpTime(char * pIP) { int sockfd; struct sockaddr_in addr_src,addr_dst; fd_set fds; int ret; int recv_len; unsigned int buf[12]; memset(buf,0,sizeof(buf)); int addr_len; int count = 0; struct timeval recvtv; struct timeval *ptimeval; double offset; struct timeval timeout; addr_len = sizeof(struct sockaddr_in); //local memset(&addr_src, 0, addr_len); addr_src.sin_family = AF_INET; addr_src.sin_addr.s_addr = htonl(INADDR_ANY); addr_src.sin_port = htons(0); //remote memset(&addr_dst, 0, addr_len); addr_dst.sin_family = AF_INET; addr_dst.sin_addr.s_addr=inet_addr(pIP); addr_dst.sin_port = htons(123);//ntp默认端口123 if(-1==(sockfd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))) { debugpri("create socket error! "); return -1; } ret = bind(sockfd, (struct sockaddr*)&addr_src, addr_len); if(-1==ret) { debugpri("bind error! "); close(sockfd); return -1; } ret = connect(sockfd, (struct sockaddr*)&addr_dst, addr_len); if(-1==ret) { debugpri("connect error! "); close(sockfd); return -1; } sendPacket(sockfd); while (count < 20) { FD_ZERO(&fds); FD_SET(sockfd, &fds); timeout.tv_sec = 0; timeout.tv_usec = 100000; ret = select(sockfd + 1, &fds, NULL, NULL, &timeout); if (0 == ret) { count++; debugpri("ret == 0 "); sendPacket(sockfd); usleep(100*1000); continue; } if(FD_ISSET(sockfd, &fds)) { recv_len = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&addr_dst, (socklen_t*)&addr_len); if(-1==recv_len) { debugpri("recvfrom error "); close(sockfd); return -1; } else if(recv_len > 0) { debugpri("receiv data "); getNewTime(buf,ptimeval); debugpri("sec = %d usec = %d",ptimeval->tv_sec ,ptimeval->tv_usec); break; } } else { debugpri("count %d ",count); usleep(50*1000); count ++; } } if(count >=20) { debugpri("getNewTime timeout ! "); close(sockfd); return -1; } close(sockfd); return ptimeval->tv_sec; }
  • 相关阅读:
    WM有约(二):配置信息
    ASP+Wrod、excel打印程序示例
    用stream直接下载文件
    ASP判断gif图像尺寸的方法
    白菜世纪RSS无刷新聚合器(1221修正)
    ASP.NET常用代码
    图片超过规定的大小就按原图片大小缩小
    javascript弹出窗口总结
    asp excel sql 关系大总结
    打开窗口
  • 原文地址:https://www.cnblogs.com/jieliujas/p/10723981.html
Copyright © 2011-2022 走看看