Skip to content

Instantly share code, notes, and snippets.

@maekawatoshiki
Last active August 29, 2015 14:12
Show Gist options
  • Save maekawatoshiki/cc927a6970675b152bd5 to your computer and use it in GitHub Desktop.
Save maekawatoshiki/cc927a6970675b152bd5 to your computer and use it in GitHub Desktop.
NTP
#include <cstdio>
#include <cstring>
#include <winsock2.h>
#include <ctime>
#include <iostream>
#include <string>
#pragma comment(lib, "ws2_32.lib")
using namespace std;
#define Years70 2208988800
class NTP
{
private:
struct NTP_Packet
{
int Control_Word;
int root_delay;
int root_dispersion;
int reference_identifier;
long long int reference_timestamp;
long long int originate_timestamp;
long long int receive_timestamp;
int transmit_timestamp_seconds;
int transmit_timestamp_fractions;
};
unsigned short server_port; // サーバのポート番号
unsigned short get_port; // 受信するポート番号
WORD wSocketVersion;
SOCKET udp_sock;
struct sockaddr_in addr_udp;
struct sockaddr_in addrServer;
struct hostent* ser_hostent;
struct NTP_Packet SendNtp;
struct NTP_Packet recvNtpTime;
struct timeval wait_time;
fd_set rdps;
int addr_size;
int nError;
int socks_ret;
unsigned long ServerIP;
time_t ntpTime;
public:
string server_name;
NTP();
time_t getTime();
};
NTP::NTP() :server_port(123), get_port(1017), addr_udp({ 0 }), addrServer({ 0 }),
SendNtp({ htonl(0x0B000000) }), recvNtpTime({ 0 }), wait_time({ 0 })
{
}
time_t NTP::getTime()
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) return -1;
{/* 初期化類 */
addr_udp.sin_family = AF_INET;
addr_udp.sin_port = htons(get_port);
addr_udp.sin_addr.s_addr = INADDR_ANY;
addr_size = sizeof(addrServer);
ser_hostent = gethostbyname(server_name.c_str());
ServerIP = *(unsigned long *)ser_hostent->h_addr_list[0];
wait_time.tv_sec = 5; // タイムアウト時間
}
udp_sock = socket(PF_INET, SOCK_DGRAM, 0);
if (udp_sock == INVALID_SOCKET) return -1;
bind(udp_sock, (sockaddr *)&addr_udp, sizeof(addr_udp));
addrServer.sin_family = AF_INET;
addrServer.sin_port = htons((unsigned short)server_port);
addrServer.sin_addr.s_addr = ServerIP;
// サーバを指定して NTP パケットを送信する
socks_ret = sendto(udp_sock, (const char *)&SendNtp, sizeof(SendNtp), 0, (struct sockaddr *)&addrServer, sizeof(addrServer));
if (socks_ret == SOCKET_ERROR)
{
closesocket(udp_sock); return -1;
}
FD_ZERO(&rdps); FD_SET(udp_sock, &rdps);
socks_ret = select(FD_SETSIZE, &rdps, 0, 0, &wait_time);
if (socks_ret == SOCKET_ERROR)
{
closesocket(udp_sock); return -1;
}
if (socks_ret == 0)
{
closesocket(udp_sock); return -1;
}
if (FD_ISSET(udp_sock, &rdps) == FALSE)
{
closesocket(udp_sock); return -1;
}
socks_ret = recvfrom(udp_sock, (char *)&recvNtpTime, sizeof(recvNtpTime), 0, (struct sockaddr *)&addrServer, &addr_size);
if (socks_ret == SOCKET_ERROR)
{
closesocket(udp_sock); return -1;
}
closesocket(udp_sock);
WSACleanup();
// UNIX 時間に変換
ntpTime = ntohl(recvNtpTime.transmit_timestamp_seconds) - Years70;
return ntpTime;
}
int main(void)
{
time_t ntpTime = 0, localTime = 0;
long diff = 0;
tm *now;
NTP ntp;
char str[128] = { 0 };
ntp.server_name = "ntp.nict.jp";
for (int i = 0; i<3; i++)
{
memset(str, 0, sizeof(str));
ntpTime = ntp.getTime();
if (ntpTime == -1) return -1;
now = localtime(&ntpTime);
sprintf(str, "time %u:%u:%u", now->tm_hour, now->tm_min, now->tm_sec);
system(str);
Sleep(1000);
}
/*
ntpTime = ntp.getTime();
now = localtime(&ntpTime);
memset(str, 0, sizeof(str));
sprintf(str, "time %u:%u:%u", now->tm_hour, now->tm_min, now->tm_sec);
system(str);
Sleep(100);
*/
return 0;
}// Copyright (C) 2015 MAEKAWA TOSHIKI
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment