63 lines
No EOL
2.2 KiB
C++
63 lines
No EOL
2.2 KiB
C++
#include <iostream>
|
|
#include <iomanip>
|
|
#include <chrono>
|
|
#include <cstring>
|
|
#include <asio.hpp>
|
|
|
|
const int NTP_PORT = 123;
|
|
const int NTP_PACKET_SIZE = 48;
|
|
|
|
void queryNTPServer(const std::string& server) {
|
|
try {
|
|
asio::io_context io_context;
|
|
|
|
asio::ip::udp::resolver resolver(io_context);
|
|
asio::ip::udp::endpoint endpoint = *resolver.resolve(server, std::to_string(NTP_PORT)).begin();
|
|
|
|
asio::ip::udp::socket socket(io_context);
|
|
socket.open(asio::ip::udp::v4());
|
|
|
|
std::array<unsigned char, NTP_PACKET_SIZE> request{};
|
|
request[0] = 0b11100011;
|
|
|
|
auto start_time = std::chrono::high_resolution_clock::now();
|
|
|
|
socket.send_to(asio::buffer(request), endpoint);
|
|
|
|
std::array<unsigned char, NTP_PACKET_SIZE> response{};
|
|
asio::ip::udp::endpoint sender_endpoint;
|
|
socket.receive_from(asio::buffer(response), sender_endpoint);
|
|
|
|
auto end_time = std::chrono::high_resolution_clock::now();
|
|
std::chrono::duration<double> ping = end_time - start_time;
|
|
|
|
const unsigned long long NTP_TIMESTAMP_DELTA = 2208988800ULL;
|
|
unsigned long long seconds = (static_cast<unsigned long long>(response[40]) << 24) |
|
|
(static_cast<unsigned long long>(response[41]) << 16) |
|
|
(static_cast<unsigned long long>(response[42]) << 8) |
|
|
static_cast<unsigned long long>(response[43]);
|
|
seconds -= NTP_TIMESTAMP_DELTA;
|
|
|
|
std::time_t time = static_cast<std::time_t>(seconds);
|
|
std::tm* utc_time = std::gmtime(&time);
|
|
|
|
std::cout << "Details of " << server << "\n";
|
|
std::cout << "Time: " << std::put_time(utc_time, "%H:%M:%S") << " UTC\n";
|
|
std::cout << "Date: " << std::put_time(utc_time, "%Y-%m-%d") << "\n";
|
|
std::cout << "Ping: " << std::fixed << std::setprecision(3) << ping.count() * 1000 << " ms\n";
|
|
|
|
} catch (const std::exception& e) {
|
|
std::cerr << "Error: " << e.what() << "\n";
|
|
}
|
|
}
|
|
|
|
int main(int argc, char* argv[]) {
|
|
if (argc != 2) {
|
|
std::cerr << "Usage: " << argv[0] << " <NTP server>\n";
|
|
return 1;
|
|
}
|
|
|
|
std::string server = argv[1];
|
|
queryNTPServer(server);
|
|
return 0;
|
|
} |