使用SNTP(Windows C )从服务器获取时间/日期
Get time/date from server with sntp(windows c++)
我正在搜索C/C 的工作代码,该代码从服务器(ntp.belnet.be)获得时间和日期。它与UDP一起使用,并使用端口123。
有人可以帮忙吗?
//sending pakket
memset(&sntp_msg_header, 0, sizeof sntp_msg_header);
sntp_msg_header.flags = 27;
sntp_msg_header.originate_timestamp_secs = time(NULL);
// Get data in rxmsg
...
...
// print time
timeval = ntohl(rxmsg.transmit_timestamp_secs) - ((70ul * 365ul + 17ul) * 86400ul);
printf("%s", ctime(&timeval));
这就是我到目前为止所拥有的。但是我无法从中获得正确的数据。我希望这是更多信息。
如果找到了:
import socket
import struct
import sys
import time
TIME1970 = 2208988800L # Thanks to F.Lundh
client = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
data = 'x1b' + 47 * ' '
client.sendto( data, ( sys.argv[1], 123 ))
data, address = client.recvfrom( 1024 )
if data:
print 'Response received from:', address
t = struct.unpack( '!12I', data )[10]
t -= TIME1970
print 'tTime=%s' % time.ctime(t)
,但它在Python中。有人可以将其更改为C ,还是有一个转换器?
这就是我使用的。它不是很优雅,但是应该足以使这个想法跨越。基本思想是拥有与网络发送和接收的结构相匹配的结构。反向的尼亚斯最初是不可思议的。值得一提的是,这几乎对错误条件无济于事。您需要解决这个问题。:)
#define ReverseEndianInt(x) ((x) =
((x)&0xff000000) >> 24 |
((x)&0x00ff0000) >> 8 |
((x)&0x0000ff00) << 8 |
((x)&0x000000ff) << 24)
/**
* NTP Fixed-Point Timestamp Format.
* From [RFC 5905](http://tools.ietf.org/html/rfc5905).
*/
struct Timestamp
{
unsigned int seconds; /**< Seconds since Jan 1, 1900. */
unsigned int fraction; /**< Fractional part of seconds. Integer number of 2^-32 seconds. */
/**
* Reverses the Endianness of the timestamp.
* Network byte order is big endian, so it needs to be switched before
* sending or reading.
*/
void ReverseEndian() {
ReverseEndianInt(seconds);
ReverseEndianInt(fraction);
}
/**
* Convert to time_t.
* Returns the integer part of the timestamp in unix time_t format,
* which is seconds since Jan 1, 1970.
*/
time_t to_time_t()
{
return (seconds - ((70 * 365 + 17) * 86400))&0x7fffffff;
}
};
/**
* A Network Time Protocol Message.
* From [RFC 5905](http://tools.ietf.org/html/rfc5905).
*/
struct NTPMessage
{
unsigned int mode :3; /**< Mode of the message sender. 3 = Client, 4 = Server */
unsigned int version :2; /**< Protocol version. Should be set to 3. */
unsigned int leap :2; /**< Leap seconds warning. See the [RFC](http://tools.ietf.org/html/rfc5905#section-7.3) */
unsigned char stratum; /**< Servers between client and physical timekeeper. 1 = Server is Connected to Physical Source. 0 = Unknown. */
unsigned char poll; /**< Max Poll Rate. In log2 seconds. */
unsigned char precision; /**< Precision of the clock. In log2 seconds. */
unsigned int sync_distance; /**< Round-trip to reference clock. NTP Short Format. */
unsigned int drift_rate; /**< Dispersion to reference clock. NTP Short Format. */
unsigned char ref_clock_id[4]; /**< Reference ID. For Stratum 1 devices, a 4-byte string. For other devices, 4-byte IP address. */
Timestamp ref; /**< Reference Timestamp. The time when the system clock was last updated. */
Timestamp orig; /**< Origin Timestamp. Send time of the request. Copied from the request. */
Timestamp rx; /**< Recieve Timestamp. Reciept time of the request. */
Timestamp tx; /**< Transmit Timestamp. Send time of the response. If only a single time is needed, use this one. */
/**
* Reverses the Endianness of all the timestamps.
* Network byte order is big endian, so they need to be switched before
* sending and after reading.
*
* Maintaining them in little endian makes them easier to work with
* locally, though.
*/
void ReverseEndian() {
ref.ReverseEndian();
orig.ReverseEndian();
rx.ReverseEndian();
tx.ReverseEndian();
}
/**
* Recieve an NTPMessage.
* Overwrites this object with values from the recieved packet.
*/
int recv(int sock)
{
int ret = ::recv(sock, (char*)this, sizeof(*this), 0);
ReverseEndian();
return ret;
}
/**
* Send an NTPMessage.
*/
int sendto(int sock, struct sockaddr_in* srv_addr)
{
ReverseEndian();
int ret = ::sendto(sock, (const char*)this, sizeof(*this), 0, (sockaddr*)srv_addr, sizeof(*srv_addr));
ReverseEndian();
return ret;
}
/**
* Zero all the values.
*/
void clear()
{
memset(this, 0, sizeof(*this));
}
};
您会这样使用它,也许在main()
中。
WSADATA wsaData;
DWORD ret = WSAStartup(MAKEWORD(2,0), &wsaData);
char *host = "pool.ntp.org"; /* Don't distribute stuff pointing here, it's not polite. */
//char *host = "time.nist.gov"; /* This one's probably ok, but can get grumpy about request rates during debugging. */
NTPMessage msg;
/* Important, if you don't set the version/mode, the server will ignore you. */
msg.clear();
msg.version = 3;
msg.mode = 3 /* client */;
NTPMessage response;
response.clear();
int sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
sockaddr_in srv_addr;
memset(&srv_addr, 0, sizeof(srv_addr));
dns_lookup(host, &srv_addr); /* Helper function defined below. */
msg.sendto(sock, &srv_addr);
response.recv(sock);
time_t t = response.tx.to_time_t();
char *s = ctime(&t);
printf("The time is %s.", s);
WSACleanup();
有很多获取IP和端口的方法,但是GetAddrinfo在Windows上做了不错的工作:
int dns_lookup(const char *host, sockaddr_in *out)
{
struct addrinfo *result;
int ret = getaddrinfo(host, "ntp", NULL, &result);
for (struct addrinfo *p = result; p; p = p->ai_next)
{
if (p->ai_family != AF_INET)
continue;
memcpy(out, p->ai_addr, sizeof(*out));
}
freeaddrinfo(result);
}
自然,此解决方案与海滩鲸鱼一样便携,但对我™都有用。
c/ 中的插座比大多数其他语言(尤其是被解释和较新的汇编)的插座略愉快。
为什么不使用
的官方实施- http://ntp.org/downloads.html
当然,NTP需要mingw,但是那里有一些库。
- http://www.hillstone-software.com/hs_ntp_details.htm(它不是免费的,但可以免费尝试,也不是必需的)
Windows自服务器2000版本以来还具有NTP内置。我无法验证它,但是它至少应该在系统上起作用。
。-
w32tm /help
(查找/query
部分) - 更多文档:http://technet.microsoft.com/en-us/library/cc773263(v=ws.10).aspx
相关文章:
- 如何从远程 SFTP 服务器获取 HH-MM-SS 时间戳格式的文件列表
- 如何使用软化工具包从 OPC UA 服务器异步读取操作回调中的数据值响应中获取 NodeId 详细信息
- 如何在C++中使用带有SFML的http reqest从节点.js服务器获取数据?
- C++ UDP 服务器在获取客户端地址配置时发送消息
- 从 c++ 服务器获取
- 如何使用 C++ 中的 cpprestsdk 发布 json 数据并从本地服务器获取响应
- 尝试重新连接到服务器时获取错误提升 asio 连接超时
- 多线程套接字编程服务器仅从 1 个客户端线程获取消息
- 可视化如何使用C++程序获取DHCPV6服务器IP.我尝试使用DHCPv6RequestParams,但总是收到错误代码
- 如何在Qt中获取主DNS服务器和辅助DNS服务器
- 如何将C++应用程序与节点.js服务器连接以获取 JSON 数据
- 使用SNTP(Windows C )从服务器获取时间/日期
- CORBA客户端/服务器应用程序,从服务器获取信息(空值)
- 在Javascript服务器应用程序之后获取HTML
- 如何将自动递增的主键的数据从 sql 服务器获取到我的数据网格视图
- 如何使用套接字实现服务器客户端编程,在套接字中服务器向客户端发送消息而不从客户端获取请求
- 无法在 gSOAP 服务器中获取 SOAP 客户端的 IP 地址
- WinInet - 如何在 301 重定向后获取服务器 URL
- 如何获取服务器的主机名
- 如何获取"服务器控制台"