开源代码下载地址:https://codeload.github.com/yuanrw/tcp-server-client/zip/master
下载后可以直接根据Readme编译linux版本运行
ntp_client
使用NTP协议获取网络时间戳,提供的 C/C++ 源码支持 Windows 和 Linux(CentOS) 两大平台。
Winodws 平台上编译与测试
在 VC 的命令行环境下,使用 nmake /f Makefile.mk 命令进行编译,输出的测试程序为
ntp_cli_test.exe ,执行该程序,即可看到测试结果。
Linux 平台上编译与测试
# make
# ./ntp_cli_test
依次执行上面的命令,即可看到测试结果。
源码说明
- VxDType.h: 定义通用数据类型的头文件。
- VxNtpHelper.h:使用NTP协议获取网络时间戳所提供的 API 与相关数据定义的头文件。
- VxNtpHelper.cpp:VxNtpHelper.h中提供的操 API 实现源码文件。
- main.cpp:接口调用流程(测试程序)。
测试程序的输出样例信息如下:
1.cn.pool.ntp.org -> 193.228.143.22
time1 : 2018-11-16_18-43-43.126
time2 : 2018-11-16_18-43-43.245
time3 : 2018-11-16_18-43-43.245
time4 : 2018-11-16_18-43-43.419
timev : 2018-11-16_18-43-43.391
timec : 2018-11-16_18-43-43.419
1.cn.pool.ntp.org : 2018-11-16_18-43-43.391
- time1 : 客户端 发送一个NTP报文给 服务端,该报文带有它离开 客户端 时的时间戳 (T1)。
- time2 : 当此NTP报文到达 服务端 时,服务端 加上自己的时间戳 (T2)。
- time3 : 当此NTP报文离开 服务端 时,服务端 再加上自己的时间戳 (T3)。
- time4 : 当 客户端 接收到该应答报文时,客户端 的本地时间戳 (T4)。
- timev : 同步到的时间戳
T = T4 + ((T2 - T1) + (T3 - T4)) / 2;
。 - timec : 系统当前的时间。
具体项目中的应用,参看 main.cpp 中的调用流程。
定义成接口
头文件:
/**
- @brief 获取服务器时间。
- @param [in ] value : 对应不同的ntp服务域名
- @param [in ] *result : 调用接口的结果,0:success
- @return x_int64_t
-
- 成功,返回 时间;
-
- 失败,返回 0。
*/
x_uint64_t getNtpTime(int value,int *result);
cpp文件:
x_uint64_t getNtpTime(int value,int *result)
{
int xit_err = -1;
x_ntp_time_context_t xnpt_timec;
memset(&xnpt_timec,0,sizeof(xnpt_timec));
x_uint64_t xut_timev = 0ULL;
//======================================
std::vector< std::string > xvec_ntp_host;
switch(value)
{
case 0:
xvec_ntp_host.push_back(std::string("0.cn.pool.ntp.org"));
break;
case 1:
xvec_ntp_host.push_back(std::string("1.cn.pool.ntp.org"));
break;
case 2:
xvec_ntp_host.push_back(std::string("2.cn.pool.ntp.org"));
break;
case 3:
xvec_ntp_host.push_back(std::string("3.cn.pool.ntp.org"));
break;
default:
xvec_ntp_host.push_back(std::string("cn.pool.ntp.org"));
break;
}
//======================================
for (std::vector< std::string >::iterator itvec = xvec_ntp_host.begin(); itvec != xvec_ntp_host.end(); ++itvec)
{
xut_timev = 0ULL;
xit_err = ntp_get_time(itvec->c_str(), NTP_PORT, 5000, &xut_timev);
memcpy(result,&xit_err,sizeof(xit_err));
if (0 == xit_err)
{
printf("xut_timev = %lld\n", xut_timev);
ntp_tmctxt_bv(xut_timev, &xnpt_timec); // 转换成 年-月-日_时-分-秒.毫秒 的时间信息
ts_output(itvec->c_str(), &xnpt_timec); // 输出时间信息
}
else
{
// 请求失败,可能是因为应答超时......
printf(" %s return error code : %d\n", itvec->c_str(), xit_err);
}
}
//======================================
return xut_timev;
}
由其他函数调用
#include “VxNtpHelper.h”
#if 1
x_uint64_t ntpTime;
struct timespec tmp;
int ntpResult=-1;
int setSystemTimeRsult=-1;
memset(&ntpTime,0,sizeof(ntpTime));
memset(&tmp,0,sizeof(tmp));
//Set Android time zone
system("setprop persist.sys.timezone CST+8");
for(int i=0;i<repeatCount;i++)
{
ntpTime = getNtpTime(i,&ntpResult);//单位为100ns
if(ntpResult == 0)
break;
else
if(ntpResult == 7 || ntpResult == 11)
printf("getNtpTime() ntpResult = %d ntpTime = %d : 请检查网络连接 , repeat 3 times : No.%d \n",ntpResult,ntpTime,i+1);
else
printf("getNtpTime() ntpResult = %d \n", ntpResult);
}
if(ntpResult == 0)
{
tmp.tv_sec = ntpTime/10000000;
tmp.tv_nsec = (ntpTime%10000000)*100;
for(int nCount=0;nCount<repeatCount;nCount++)
{
if(clock_settime(CLOCK_REALTIME, &tmp))//-1
{
perror("setclock mtime error");
}
else//0
{
printf("setclock success \n");
break;
}
}
}
#endif
编译生成可执行文件
生成android可以运行的程序(aarch64-linux-android-g++请自行安装环境)
aarch64-linux-android-g++ xx.cpp main.cpp xx.c VxDType.h VxNtpHelper.h VxNtpHelper.cpp -o test_Android_netTime -fPIE -pie
设置时区
时间同步后假如时间与看到网络时间不一致(一般多或少8个小时),这是因为时区不对
可按下面的方法设置时区:
QNX设置时区:env TZ=CTS-8 && export TZ=CST-8 && setconf_CS_TIMEZONE CTS-8
Android设置时区:setprop persist.sys.timezone CST+8
根据当前所处地区的所处时区再做对应修改
今天的文章C++ ntp同步网络时间,代码实现分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/30499.html