我正在尝试创建与某个ntp服务器连接的ntp客户端,以同步其时钟

时间:2018-03-27 08:56:36

标签: c++ ntp

我尝试通过创建一个带有ntp请求的数据包来创建一个ntp客户端,然后发送给服务器。但我无法编码计算偏移量并根据该偏移量设置时间。虽然我已经做了什么,但我得到了一些偏移值,但我不确定这个值是否正确。如果有人可以帮助我。提前谢谢。

#include <stdio.h>
#define NTP_HDR_LEN         48
#define FRAC                4294967296
struct ntp_packet
{
    uint8_t li_vn_mode;      // Eight bits. li, vn, and mode.
                       // li.   Two bits.   Leap indicator.
                       // vn.   Three bits. Version number of the protocol.
                       // mode. Three bits. Client will pick mode 3 for client.
    uint8_t stratum;         // Eight bits. Stratum level of the local clock.
    uint8_t poll;            // Eight bits. Maximum interval between successive messages.
    uint8_t precision;       // Eight bits. Precision of the local clock.
    uint32_t rootDelay;      // 32 bits. Total round trip delay time.
    uint32_t rootDispersion; // 32 bits. Max error aloud from primary clock source.
    uint32_t refId;          // 32 bits. Reference clock identifier.
    uint32_t refTm_s;
    uint32_t refTm_f;       // 64 bits. Reference time-stamp seconds.
    uint32_t origTm_s;
    uint32_t origTm_f;      // 64 bits. Originate time-stamp seconds.
    uint32_t rxTm_s;
    uint32_t rxTm_f;        // 64 bits. Received time-stamp seconds.
    uint32_t txTm_s;         // 32 bits and the most important field the client cares about. Transmit time-stamp seconds.
    uint32_t txTm_f;         // 32 bits. Transmit time-stamp fraction of a second.
}packet;
char sendBuf[2048];
char rcvBuf[2048];
struct timeval txt, trecv, tsend;

void adjust_time(signed long long off)
{
unsigned long long ntp_tym;
struct timeval unix_time;
gettimeofday(&unix_time, NULL);
ntp_tym = off + ((ntohl(txt.tv_sec + 2208988800)) +  (ntohl(txt.tv_usec) / 
1e6));
unix_time.tv_sec = ntp_tym >> 32;
unix_time.tv_usec = (long)(((ntp_tym - unix_time.tv_sec) << 32) / FRAC * 
1e6);
settimeofday(&unix_time, NULL);
}

void CreateSocket()
{
sourceIp = "192.168.1.109";
hostNameInteractive = "139.143.5.30";
source_dest_Port = 123;
uint32_t s_recv_s, s_recv_f, s_trans_s, s_trans_f;
unsigned long long t1, t2, t3, t4;
signed long long offs;
double offset;

if ((sock_raw = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL))) < 0)
{
    perror ("socket() failed to get socket descriptor for using ioctl() ");
    exit(1);
}
    CreateNtpHeader();
    SendRecv();

    gettimeofday(&trecv, NULL);
    struct ntp_packet *npkt = (struct ntp_packet*)(rcvBuf);
    s_recv_s = ntohl(npkt->rxTm_s);
    s_recv_f = ntohl(npkt->rxTm_f);
    s_trans_s = ntohl(npkt->txTm_s);
    s_trans_f = ntohl(npkt->txTm_f);
    t1 = ((ntohl(txt.tv_sec + 2208988800)) +  (ntohl(txt.tv_usec) / 
   1000000));
    t4 = ((ntohl(trecv.tv_sec + 2208988800)) + (ntohl(trecv.tv_usec) / 
   1000000));
    t2 = ((s_recv_s) + (s_recv_f / 1e12));
    t3 = ((s_trans_s) + (s_trans_f / 1e12));
    offs = (((t2 - t1) + (t3 - t4))/2);
    offset = ((double)offs) / FRAC;
    std::cout<<"offset : "<<offset<<" sec"<<std::endl;
    adjust_time(offs);
    close(sock_raw);
 }

void CreateNtpHeader()
{
    struct ntp_packet *pkt = (struct ntp_packet *)(sendBuf);
    gettimeofday(&txt, NULL);
    pkt->li_vn_mode = 0xe3;
    pkt->stratum = 0;
    pkt->poll = 3;
    pkt->precision = 0xfa;
    pkt->rootDelay = 0x00000100;
    pkt->rootDispersion = 0x00000100;
    pkt->refId = 0;
    pkt->refTm_s = 0;
    pkt->refTm_f = 0;
    pkt->origTm_s = 0;
    pkt->origTm_f = 0;
    pkt->rxTm_s = 0;
    pkt->rxTm_f = 0;
    pkt->txTm_s = htonl(txt.tv_sec + 2208988800);
    pkt->txTm_f = htonl(txt.tv_usec);
   }

int main(int arg, char* args[])
{
CreateSocket();
return 0;
}

这不是完整的代码。这只是我遇到问题的代码的一部分。我已经包含了所有需要的标题。如果需要其他任何东西或需要任何解释,请告诉我。

0 个答案:

没有答案