首页
社区
课程
招聘
[原创]时间校对:UDP发NTP协议封包来获取时间(2,从NTP协议中解析时间戳并设置本机时间)
发表于: 2014-9-26 13:39 6311

[原创]时间校对:UDP发NTP协议封包来获取时间(2,从NTP协议中解析时间戳并设置本机时间)

2014-9-26 13:39
6311

之前说了发ntp查询包获取ntp回包.
http://bbs.pediy.com/showthread.php?p=1318896

这里说下解析出的时间戳的使用方法
NTPPack.TransmitTime
是NTP包离开NTP服务器时候的时间戳

首先注意.之前我将NTP时间戳定义为
typedef struct ntptime_t   
{  
UINT dwHighDateTime;
UINT dwLowDateTime;
}ntptime;

其中的high 高位其实是时间戳中的秒数
低位则是余出来的纳秒数
我们在发查询包之前 可以
ULONG RealTimeOut = GetTickCount();
获取下当时的count
然后再收到回包之后
RealTimeOut = (GetTickCount() - RealTimeOut) / 2;
即可获取延迟

我们可以将高位转换为time_t
time_t ntp_time = ntohl(NTPRecvPack.TransmitTime.dwHighDateTime) - 2208988800

然后将低位转换为系统的毫秒值
float Splitseconds;
  Splitseconds = (float)ntohl(NTPRecvPack.TransmitTime.dwLowDateTime);
  Splitseconds = (float)0.000000000200 * Splitseconds;
  Splitseconds = (float)1000.0 * Splitseconds;

然后进行精度纠正:
if ((Splitseconds + RealTimeOut) > 1000)
{
       Splitseconds += RealTimeOut % 1000;
       ntp_time += RealTimeOut % 1000;
}else if((Splitseconds + RealTimeOut) = 1000)
{
      ntp_time ++;
}else
{
      Splitseconds += RealTimeOut;
}

然后我们将获取的Splitseconds与ntp_time转换为SYSTEMTIME

TimeStamp->wYear = lpLocalTime.tm_year + 1900;//时间戳是从1900年开始算
  TimeStamp->wMonth = lpLocalTime.tm_mon + 1;//tm是从0开始 systemtime是从1开始
  TimeStamp->wDay = lpLocalTime.tm_mday;
  TimeStamp->wHour = lpLocalTime.tm_hour;
  TimeStamp->wMinute = lpLocalTime.tm_min;
  TimeStamp->wSecond = lpLocalTime.tm_sec;
        TimeStamp->wMilliseconds = (USHORT)Splitseconds;

然后现在就可以调用
sprintf_s(Localtimestr,MAX_PATH,"%d-%d-%d %d:%d:%d",
    TimeStamp.wYear,TimeStamp.wMonth,TimeStamp.wDay,
    TimeStamp.wHour,TimeStamp.wMinute,TimeStamp.wSecond);
格式化为人常年的时间格式.
或者调用
SetLocalTime(&TimeStamp);
来设置本机时间了

http://blog.shajincheng.com/post/93.html


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 3
支持
分享
最新回复 (1)
雪    币: 11
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
不错 整好需要用到 NTP 协议来做个东西
2014-9-26 14:46
0
游客
登录 | 注册 方可回帖
返回
//