NTP报文的格式如下:
LI 闰秒标识器,占用2个bit。0 即可。
VN 版本号,占用3个bits,表示NTP的版本号,现在为3
Mode 模式,占用3个bits,表示模式。 3 表示 client, 2 表示 server
stratum(层),占用8个bits。不清楚怎么用
Poll 测试间隔,占用8个bits,表示连续信息之间的最大间隔。不清楚怎么用
Precision 精度,占用8个bits,,表示本地时钟精度。 不清楚怎么用
Root Delay根时延,占用8个bits,表示在主参考源之间往返的总共时延。 不清楚怎么用
Root Dispersion根离散,占用8个bits,表示在主参考源有关的名义错误。 不清楚怎么用
Reference Identifier参考时钟标识符,占用8个bits,用来标识特殊的参考源。不同的 NTP server 改字段不一样
参考时间戳,64bits时间戳,本地时钟被修改的最新时间。一般由 server 端填写,表示 server 上次同步时间戳的时间点
原始时间戳,客户端发送的时间,64bits。即公式中的 t1 。client 请求时必须填写,server 端响应时、回写请求包里的该字段
接受时间戳,服务端接受到的时间,64bits。即公式中的 t2 。server 端填写
传送时间戳,服务端送出应答的时间,64bits。即公式中的 t3。server 端填写
认证符(可选项)
其中,四个时间戳:
- ReferenceTimeStamp 参考时间戳
- OriginateTimeStamp 原始时间戳 T1
- ReceiveTimeStamp 接收时间戳 T2
- TransmitTimeStamp 传送时间戳 T3
- 还差一个T4,T4为客户端接收到响应报文时的时间戳
- 计算公式:NTP报文往返时延:Delay=(T4-T1)-(T3-T2)
- 时间差:Offset=((T2-T1)+(T3-T4))/2
计算出这两个,就是需要的值
如何计算:
刚开始直接就代入了公式,用加减法计算,但是算出来的值特别大
后来找了很久,才发现应该用msecsTo(),不知道为啥,明明之前加减法的时候,已经全部转换成了毫秒,还是不行,现在将它转换成日期,然后用这个函数,算出来就是对的
OriginateTimeStamp=newTime.mid(24,8);
ReceiveTimeStamp=newTime.mid(32,8);
TransmitTimeStamp = newTime.right(8);
DestinationTimeStamp=CURRENT_NTP_MILLION_SECOND;
qint64 t1=byte64ToMillionSecond(OriginateTimeStamp);
qint64 t2=byte64ToMillionSecond(ReceiveTimeStamp);
qint64 t3=byte64ToMillionSecond(TransmitTimeStamp);
qint64 t4=CURRENT_NTP_MILLION_SECOND;
QDateTime d1;
QDateTime d2;
QDateTime d3;
QDateTime d4;
d1.setMSecsSinceEpoch(t1);
qDebug()<<"t1:"<<d1;
d2.setMSecsSinceEpoch(t2-2208988800000);
qDebug()<<"t2:"<<d2;
d3.setMSecsSinceEpoch(t3-2208988800000);
qDebug()<<"t3:"<<d3;
d4.setMSecsSinceEpoch(t4-2208988800000);
qDebug()<<"t4:"<<d4;
//qDebug()<<"d2-d1+d3-d4"<<(d2.toMSecsSinceEpoch()-d1.toMSecsSinceEpoch()+d3.toMSecsSinceEpoch()-d4.toMSecsSinceEpoch())/2;
qint64 offset;
offset=(d1.msecsTo(d2)+d4.msecsTo(d3))/2;
qint64 delay;
delay=d1.msecsTo(d4)-d2.msecsTo(d3);
不知道怎样同步时间,利用时间差对本地时间进行校准,本地时间=T3+Offset这样同步后,时差没有变小
在另一篇文章上看到 本地时间=T3+delay/2 这样同步之后,时差确实变小了,但是不知道到底对不对