ㅇㅇ 님이 쓰신 글 :
: 소스를 찾아보니 MFC로 하는 것 밖에 없더라구요. 윈도우 함수로 타임서버와 시간 동기화를 할 수 있는 방법이 있나요? 아니면 어쩔 수 없이 MFC dll 만들어야 하나요?
답변:
NTP 프로토콜이야 뻔한거 아닙니까.
에러체크, Non-blocking 사용하지 않고 간단하게 다음과 같이
NTP 패킷 전송을 udp 로 구현할 수 있지요.
#include
#include
#include
#include
#pragma comment(lib, "ws2_32.lib")
#define SWAP(x) ((x) = \
((x)&0xff000000) >> 24 | \
((x)&0x00ff0000) >> 8 | \
((x)&0x0000ff00) << 8 | \
((x)&0x000000ff) << 24)
int main()
{
WSADATA wsaData;
::WSAStartup(MAKEWORD(2, 0), &wsaData);
// NTP packet
unsigned char packet[48] { 0x1b };
SOCKET sock = ::socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
sockaddr_in srv_addr {};
struct addrinfo *addrTmp = nullptr;
getaddrinfo("kr.pool.ntp.org", "ntp", NULL, &addrTmp);
for (struct addrinfo *p = addrTmp; p; p = p->ai_next)
{
if (p->ai_family == AF_INET) {
memcpy(&srv_addr, p->ai_addr, sizeof(srv_addr));
break;
}
}
freeaddrinfo(addrTmp);
// send NTP query packet
::sendto(sock, (const char*)packet, sizeof(packet), 0, (sockaddr*)&srv_addr, sizeof(srv_addr));
// receive NTP response
::recv(sock, (char*)packet, sizeof(packet), 0);
PDWORD pd = ((PDWORD)&packet + 10);
// swap machine endian
SWAP(*pd);
// base 1970
time_t t = ((time_t)*((PDWORD)&packet + 10)) - 2208988800ULL;
char buf[1024];
// convert NTP time_t to struct tm local system time-zone
strftime(buf, 1023, "[%Y-%m-%d %p %H:%M:%S]", localtime(&t));
printf("network time server query: %s\n", buf);
WSACleanup();
return 0;
}
|