windows10搭建NTP服务器过程及验证测试_win10开启ntp服务-CSDN博客

记录工作实践:IEC61850协议通信过程中,需要通过SNTP协议进行对时功能,为验证此功能所以在windows11平台上面搭建NTP服务器,在开发板上面运行对时程序从而实现对时功能。

windows11搭建SNTP服务步骤:经查询Windows系统本身是可以作NTP时间同步服务器的,无需安装其它软件,只需要修改一些配置。

1.修改注册表:使用win + R 组合键在运行窗口中输入regedit,打开注册表编辑器。

2.修改以下注册表内容:

计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer,把Enabled设置为1

计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\Config,并把AnnounceFlags的值设置为5(系统默认为a)

3.启动NTP服务:通过管理员身份运行CMD命令行,依次输入命令

输入net stop w32time  输出以下信息表示没有打开NTP服务

输入net start w32time 启动服务,下图表示启动成功

4.本地测试

在cmd窗口中输入w32tm /stripchart /computer:192.168.1.100 ,如果有回显则服务正常。

以上表示为NTP服务搭建成功。

NTP服务功能测试:测试程序如下

1.sntp.c

#include "sntp.h"struct s_fixedpt {    uint16_t    intpart;    uint16_t    fracpart;}; struct l_fixedpt {    uint32_t    intpart;    uint32_t    fracpart;};  struct ntphdr {#if __BYTE_ORDER == __BID_ENDIAN    unsigned int    ntp_li : 2;    unsigned int    ntp_vn : 3;    unsigned int    ntp_mode : 3;#endif#if __BYTE_ORDER == __LITTLE_ENDIAN    unsigned int    ntp_mode : 3;    unsigned int    ntp_vn : 3;    unsigned int    ntp_li : 2;#endif    uint8_t         ntp_stratum;    uint8_t         ntp_poll;    int8_t          ntp_precision;    struct s_fixedpt    ntp_rtdelay;    struct s_fixedpt    ntp_rtdispersion;    uint32_t            ntp_refid;    struct l_fixedpt    ntp_refts;    struct l_fixedpt    ntp_orits;    struct l_fixedpt    ntp_recvts;    struct l_fixedpt    ntp_transts;};  in_addr_t inet_host(const char* host){    in_addr_t saddr;    struct hostent* hostent;     if ((saddr = inet_addr(host)) == INADDR_NONE)    {        if ((hostent = gethostbyname(host)) == NULL)            return INADDR_NONE;         memmove(&saddr, hostent->h_addr, hostent->h_length);    }     return saddr;}  int get_ntp_packet(void* buf, size_t* size){    struct ntphdr* ntp;    struct timeval tv;      if (!size || *size < NTP_HLEN)        return -1;     memset(buf, 0, *size);     ntp = (struct ntphdr*)buf;    ntp->ntp_li = NTP_LI;    ntp->ntp_vn = NTP_VN;    ntp->ntp_mode = NTP_MODE;    ntp->ntp_stratum = NTP_STRATUM;    ntp->ntp_poll = NTP_POLL;    ntp->ntp_precision = NTP_PRECISION;     gettimeofday(&tv, NULL);    ntp->ntp_transts.intpart = htonl(tv.tv_sec + JAN_1970);    ntp->ntp_transts.fracpart = htonl(USEC2FRAC(tv.tv_usec));     *size = NTP_HLEN;    return 0;}  void print_ntp(struct ntphdr* ntp){    time_t time;     printf("LI:\t%d \n", ntp->ntp_li);    printf("VN:\t%d \n", ntp->ntp_vn);    printf("Mode:\t%d \n", ntp->ntp_mode);    printf("Stratum:\t%d \n", ntp->ntp_stratum);    printf("Poll:\t%d \n", ntp->ntp_poll);    printf("precision:\t%d \n", ntp->ntp_precision);     printf("Route delay:\t %lf \n",        ntohs(ntp->ntp_rtdelay.intpart) + NTP_REVE_FRAC16(ntohs(ntp->ntp_rtdelay.fracpart)));    printf("Route Dispersion:\t%lf \n",        ntohs(ntp->ntp_rtdispersion.intpart) + NTP_REVE_FRAC16(ntohs(ntp->ntp_rtdispersion.fracpart)));    printf("Referencd ID:\t %d \n", ntohl(ntp->ntp_refid));      time = ntohl(ntp->ntp_refts.intpart) - JAN_1970;    printf("Reference:\t%d %ld %s \n",        ntohl(ntp->ntp_refts.intpart) - JAN_1970,        FRAC2USEC(ntohl(ntp->ntp_refts.fracpart)),        ctime(&time));     time = ntohl(ntp->ntp_orits.intpart) - JAN_1970;    printf("Originate:\t%d %d frac=%ld (%s) \n",        ntohl(ntp->ntp_orits.intpart) - JAN_1970,        FRAC2USEC(ntohl(ntp->ntp_orits.fracpart)),        ntohl(ntp->ntp_orits.fracpart),        ctime(&time));     time = ntohl(ntp->ntp_recvts.intpart) - JAN_1970;    printf("Receive:\t%d %d (%s) \n",        ntohl(ntp->ntp_recvts.intpart) - JAN_1970,        FRAC2USEC(ntohl(ntp->ntp_recvts.fracpart)),        ctime(&time));     time = ntohl(ntp->ntp_transts.intpart) - JAN_1970;    printf("Transmit:\t%d %d (%s) \n",        ntohl(ntp->ntp_transts.intpart) - JAN_1970,        FRAC2USEC(ntohl(ntp->ntp_transts.fracpart)),        ctime(&time));}  double get_rrt(const struct ntphdr* ntp, const struct timeval* recvtv){    double t1, t2, t3, t4;     t1 = NTP_LFIXED2DOUBLE(&ntp->ntp_orits);    t2 = NTP_LFIXED2DOUBLE(&ntp->ntp_recvts);    t3 = NTP_LFIXED2DOUBLE(&ntp->ntp_transts);    t4 = recvtv->tv_sec + recvtv->tv_usec / 1000000.0;     return (t4 - t1) - (t3 - t2);}  double get_offset(const struct ntphdr* ntp, const struct timeval* recvtv){    double t1, t2, t3, t4;     t1 = NTP_LFIXED2DOUBLE(&ntp->ntp_orits);    t2 = NTP_LFIXED2DOUBLE(&ntp->ntp_recvts);    t3 = NTP_LFIXED2DOUBLE(&ntp->ntp_transts);    t4 = recvtv->tv_sec + recvtv->tv_usec / 1000000.0;     return ((t2 - t1) + (t3 - t4)) / 2;}  void usage(void){    fprintf(stderr,        "Usage : ntpclient"        " destination"        "\n"    );}  int main(){    char buf[BUFSIZE];    size_t nbytes;    int sockfd, maxfd1;    struct sockaddr_in servaddr;    fd_set readfds;    struct timeval timeout, recvtv, tv;    double offset;     servaddr.sin_family = AF_INET;    servaddr.sin_port = htons(NTP_PORT);    servaddr.sin_addr.s_addr = inet_host(NTP_SERVER);     if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)    {        perror("socket error");        exit(-1);    }     if (connect(sockfd, (struct sockaddr*)&servaddr, sizeof(struct sockaddr)) != 0)    {        perror("connect error");        exit(-1);    }     nbytes = BUFSIZE;    if (get_ntp_packet(buf, &nbytes) != 0)    {        fprintf(stderr, "construct ntp request error \n");        exit(-1);    }    send(sockfd, buf, nbytes, 0);      FD_ZERO(&readfds);    FD_SET(sockfd, &readfds);    maxfd1 = sockfd + 1;     timeout.tv_sec = TIMEOUT;    timeout.tv_usec = 0;     if (select(maxfd1, &readfds, NULL, NULL, &timeout) > 0)    {        if (FD_ISSET(sockfd, &readfds))        {            if ((nbytes = recv(sockfd, buf, BUFSIZE, 0)) < 0)            {                perror("recv error");                exit(-1);            }            //计算客户端时间与服务器端时间偏移量            gettimeofday(&recvtv, NULL);            offset = get_offset((struct ntphdr*)buf, &recvtv);            //更新系统时间            gettimeofday(&tv, NULL);            tv.tv_sec += (int)offset;            tv.tv_usec += offset - (int)offset;             if (settimeofday(&tv, NULL) != 0)            {                perror("settimeofday error");                exit(-1);            }                        /*printf("time=%s\n", ctime((time_t*)&tv.tv_sec));            char time_string[80];            strftime(time_string, sizeof(time_string), "%Y-%m-%d %H:%M:%S", localtime(&tv.tv_sec));            printf("date -s %s\n", time_string);*/        }    }     close(sockfd);     return 0;}

sntp.h 

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <unistd.h>#include <sys/select.h>#include <sys/socket.h>#include <arpa/inet.h>#include <netdb.h>#include <errno.h>#include <endian.h> #define VERSION_3           3#define VERSION_4           4#define MODE_CLIENT         3#define MODE_SERVER         4#define NTP_LI              0#define NTP_VN              VERSION_3   #define NTP_MODE            MODE_CLIENT#define NTP_STRATUM         0#define NTP_POLL            4#define NTP_PRECISION       -6#define NTP_HLEN            48#define NTP_PORT            123#define NTP_SERVER          "192.168.1.100"#define TIMEOUT             10#define BUFSIZE             1500#define JAN_1970            0x83aa7e80#define NTP_CONV_FRAC32(x)  (uint64_t) ((x) * ((uint64_t)1<<32))    #define NTP_REVE_FRAC32(x)  ((double) ((double) (x) / ((uint64_t)1<<32)))   #define NTP_CONV_FRAC16(x)  (uint32_t) ((x) * ((uint32_t)1<<16))    #define NTP_REVE_FRAC16(x)  ((double)((double) (x) / ((uint32_t)1<<16)))    #define USEC2FRAC(x)        ((uint32_t) NTP_CONV_FRAC32( (x) / 1000000.0 )) #define FRAC2USEC(x)        ((uint32_t) NTP_REVE_FRAC32( (x) * 1000000.0 )) #define NTP_LFIXED2DOUBLE(x)    ((double) ( ntohl(((struct l_fixedpt *) (x))->intpart) - JAN_1970 + FRAC2USEC(ntohl(((struct l_fixedpt *) (x))->fracpart)) / 1000000.0 ))   

2.通过交叉编译工具生成可执行程序。aarch64-linux-gnu-gcc ntp_time.c -o ntp -lpthread 交叉编译工具需与编译平台保持一致。

以下为输出结果。


原网址: 访问
创建于: 2024-06-14 15:16:31
目录: default
标签: 无

请先后发表评论
  • 最新评论
  • 总共0条评论