请教ntp对时方面的专家,最近做一个开发,需求如下:
通过 NTP 乒乓的方式实现对北斗时间同步装置及被授时设备对时偏差的监测,采用客户端(管理端)和服务器(被监测端)问答方式实现对时偏差的计算。为了提高对时偏差的精度,采用时钟装置做为监测的管理端,监测其它被授时设备,具体过程如下:
a) A 为管理端发送“监测时钟请求”的时标;
b) B 为被监测端收到“监测时钟请求”的时标;
c) C 为被监测端返回“监测时钟请求的结果”的时标;
d) D 为管理端收到“监测时钟请求的结果”的时标;
e) △t 为管理端时钟超前被监测装置内部时钟的钟差(正为相对超前,负代表相对滞后);
f) △t =[(D - C) + (A - B)]/2
问题1:我看了网络上一些代码,好像都没有具体取得以上A,B,C,D这四个时间的,各位可有相关源码,发我参考一下。
此外,我在网络上找到一段代码,源码和执行结果如下:
typedef struct
{
uint8_t li_vn_mode; // Leap indicator, version and mode
uint8_t stratum; // Stratum level of the local clock
uint8_t poll; // Maximum interval between successive messages
uint8_t precision; // Precision of the local clock
uint32_t rootDelay; // Total round trip delay time
uint32_t rootDispersion; // Max error aloud from primary clock source
uint32_t refId; // Reference clock identifier
uint32_t refTm_s; // Reference time-stamp seconds 参考时间戳
uint32_t refTm_f; // Reference time-stamp fraction of a second
uint32_t origTm_s; // Originate time-stamp seconds 原始时间戳
uint32_t origTm_f; // Originate time-stamp fraction of a second
uint32_t rxTm_s; // Received time-stamp seconds 接收时间戳
uint32_t rxTm_f; // Received time-stamp fraction of a second
uint32_t txTm_s; // Transmit time-stamp seconds 传送时间戳
uint32_t txTm_f; // Transmit time-stamp fraction of a second
} ntp_packet;
void main()
{
m_client_sockid = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
struct sockaddr_in clientSockAdd;
bzero((char *)&clientSockAdd, sizeof(clientSockAdd));
clientSockAdd.sin_family = AF_INET;
clientSockAdd.sin_port = htons(this->m_iPort);
clientSockAdd.sin_addr.s_addr = inet_addr(this->m_IP.c_str());
int iRet = -1;
ntp_packet ntpPacket;
;
memset(&ntpPacket, 0, sizeof(ntp_packet));
ntpPacket.li_vn_mode = (0x3 << 6) | (0x3 << 3) | 0x3; // NTPv4, client mode
iRet = sendto(m_client_sockid, (char *)&ntpPacket, sizeof(ntp_packet), 0, (struct sockaddr *)&clientSockAdd, sizeof(clientSockAdd));
iRet = recvfrom(m_client_sockid, (char *)&ntpPacket, sizeof(ntp_packet), 0, NULL, NULL);
cout << "iRet:" << to_string(iRet) << endl;
cout << "refTm_s:" << to_string(ntpPacket.refTm_s) << endl;
cout << "refTm_f:" << to_string(ntpPacket.refTm_f) << endl;
cout << "origTm_s:" << to_string(ntpPacket.origTm_s) << endl;
cout << "origTm_f:" << to_string(ntpPacket.origTm_f) << endl;
cout << "rxTm_s:" << to_string(ntpPacket.rxTm_s) << endl;
cout << "rxTm_f:" << to_string(ntpPacket.rxTm_f) << endl;
cout << "txTm_s:" << to_string(ntpPacket.txTm_s) << endl;
cout << "txTm_f:" << to_string(ntpPacket.txTm_f) << endl;
ntpPacket.refTm_s = ntohl(ntpPacket.refTm_s);
ntpPacket.refTm_f = ntohl(ntpPacket.refTm_f);
time_t tmTemp = (time_t)(ntpPacket.refTm_s - NTP_TIMESTAMP_DELTA);
printf("refTm: %s", ctime((const time_t *)&tmTemp));
ntpPacket.rxTm_s = ntohl(ntpPacket.rxTm_s);p
ntpPacket.rxTm_f = ntohl(ntpPacket.rxTm_f);
tmTemp = (time_t)(ntpPacket.rxTm_s - NTP_TIMESTAMP_DELTA);
printf("rxTm: %s", ctime((const time_t *)&tmTemp));
ntpPacket.txTm_s = ntohl(ntpPacket.txTm_s);
ntpPacket.txTm_f = ntohl(ntpPacket.txTm_f);
tmTemp = (time_t)(ntpPacket.txTm_s - NTP_TIMESTAMP_DELTA);
printf("txTm: %s", ctime((const time_t *)&tmTemp));
}
执行结果如下:
问题2:这个例子中的参考时间戳、原始时间戳、接收时间戳、传送时间戳与问题1中的A,B,C,D可有对应关系,如果没有,它们分别是什么意思呢?执行结果中的原始时间为什么是0,参考时间为什么是3天前的一个日期?
问题3:客户端作为发送方,其请求发出的时间和收到回复的时间都可以自己记录,看上面的程序,这两个时间好像ntp协议会自动填充到结构体中一样,不知我的理解是否正确?