• ntp 校时程序


    //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 ",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 ",leap,version,mode);
    printf("stratum=%d,poll=%d,precision=%d ",stratum,poll,precision);
    printf("################ data #################### ");
    printf("root_delay=%ld ",rpkt.root_delay);
    printf("dispersion=%ld ",rpkt.root_dispersion);
    // printf("Id=%s ",(*(int*)&rpkt.ref_id));
    printf("refh=%lx ",rpkt.reftimestamphigh);
    printf("relw=%lx ",rpkt.reftimestamplow);
    printf("orih=%lx ",rpkt.oritimestamphigh);
    printf("oril=%lx ",rpkt.oritimestamplow);
    printf("rech=%lx ",rpkt.recvtimestamphigh);
    printf("recl=%lx ",rpkt.recvtimestamplow);
    printf("trah=%lx ",rpkt.trantimestamphigh);
    printf("tral=%lx ",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(" debug information ... ");
    printf("time(NULL) is %ld ",time(NULL));
    printf("different time is %ld ",diftime);
    printf("delaytime is %ld ",delaytime);
    printf("time(NULL)+diftime+delaytime=%ld ",time(NULL)+diftime+delaytime);
    printf("tv1.tv_sec is %ld ", 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 ");
    close(fd);
    }

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

  • 相关阅读:
    【转并修改】VS2013 MVC Web项目使用内置的IISExpress支持局域网内部机器(手机、PC)访问、调试
    ASP.NET MVC4 UEditor 的上传图片配置路径
    转:Java图形化界面设计——布局管理器之FlowLayout(流式布局)其他请参考转载出处网址
    转载:win7JDK环境配置
    转载:java保留2位小数
    转载:遍历Map的四种方法
    架构模式: 远程过程调用
    架构模式: 外部配置化
    架构模式: 微服务的基底
    架构模式: 服务部署平台
  • 原文地址:https://www.cnblogs.com/zhouhbing/p/3881387.html
Copyright © 2020-2023  润新知