NTP/SNTP v4/v3 服务器/客户端 C++





5.00/5 (18投票s)
高效独立的 NTP 服务器/客户端库,使用纯 C++ 实现。
引言
在花了一些时间寻找可靠的原生 NTP 服务器和客户端实现,但一无所获后,我决定自己实现一个。其他服务器/客户端实现存在各种问题和兼容性问题。
默认情况下,服务器和客户端都不会修改机器时间(尽管它们具有此功能)。
背景
这种需求源于需要在系统上对时间同步机制进行完全控制,而无需影响系统时钟,同时监控排队请求时间的 NTP 设备。
鸣谢:Jakub Parez 在 NTP-Client 项目是一个很好的起点,地址为 https://github.com/parezj/NTP-Client/tree/master。
Using the Code
//The included unit tests show examples for both server & client.
ntp::ClientSettings cs;
cs.lts = ntp::LocalTimeSource::InternalClock;
cs.fta.delta_avg_min = std::chrono::microseconds::min();
cs.fta.delta_stdev_min = std::chrono::microseconds(500);
cs.fta.fine_adjustment_duration = std::chrono::seconds(60);
cs.error_callback = [](const ntp::IClient& client,
std::string error_string, void* userParam) {
std::cout << "NTP client error: " << error_string << std::endl;
};
cs.warnning_callback = [](const ntp::IClient& client,
std::string warn_string, void* userParam) {
std::cout << "NTP client warning: " << warn_string << std::endl;
};
cs.clockset_callback = [](const ntp::IClient& client,
ManagedClockPtr new_clock, void* userParam) {
std::cout << "NTP client clockset: " <<
new_clock->now().as_string() << std::endl;
};
auto ntp_client = ntp::IClient::create_instance();
ntp_client->init(cs);
auto res = ntp_client->query(ep, false);//once created,
//client can query a server given an endpoint.
//Server is actually a lot simpler once defining the sources of the clock:
auto ntp_server = ntp::IServer::create_instance();
ntp::IServer::ServerSettings setup;
if (use_external_time_source) {
auto mng = StartInitClientsManager(false);
mng->wait_initialzed(std::chrono::milliseconds(-1));
setup.time_source = mng;
}
setup.error_callback = [](const ntp::IServer& server,
std::string error_string, void* userParam) {
std::cout << "NTP server error: " << error_string << std::endl;
};
setup.warnning_callback = [](const ntp::IServer& server,
std::string warn_string, void* userParam) {
std::cout << "NTP server warning: " << warn_string << std::endl;
};
setup.client_serverd_callback = [](const ntp::IServer& server,
std::string client_addr, void* userParam) {
std::cout << "NTP server serverd the client " << client_addr <<std::endl;
};
if(!ntp_server->init(setup))
return false;
std::this_thread::sleep_for(std::chrono::hours(10));
关注点
我学到的一个东西是时间“同步”的复杂性,以及它对各种因素的敏感程度。
历史
- 2023年8月26日
- 初始版本
- 2023年11月22日
- 错误修复,性能改进
- 2023年11月29日
- 改进的 API
- IPv6 支持
- 更短的服务器评估时间
- 添加服务器评估方法
enum
以选择准确性而非更快的评估 - 添加协议版本控制,使用客户端设置
- 修复了服务器的根延迟和根色散传输错误
- 修复了客户端的 refid 解析错误
- 2023年12月1日
- 消息打印缓冲区溢出错误修复
- Ping 错误修复
- 改进
DateTime
结构 - 客户端:添加了对 NTP 控制消息(死亡之吻代码)的初步处理
- 2023年12月2日
- 客户端:同步过程错误修复
- 客户端:添加平滑时钟调整的选项
- 客户端:更改默认设置
- ClientsManager:通过回调公开查询结果
- 2023年12月3日
- 客户端+服务器:根色散和根延迟错误格式已修复。
- 2023年12月27日
- 添加了完整的 Linux/Ubuntu 支持。
- Codeblocks IDE 支持。
- 支持 NTP 纪元。
- 小的错误修复。
- 2024年3月3日
- 改进了闰秒指示器的处理。
- 2024年7月15日
- 为控制对请求的响应(忽略、标记为不同步、标记为拒绝访问)添加了服务器代码响应模式。
- 2024年8月8日
- 错误已修复。
- 添加了可选的动态时钟更新策略接口插件。