c/c++代码获取网络时间(从NTP授时服务器获取)

15 篇文章 0 订阅

有时候需要获取网络时间,又没有自己的服务器去返回,那么可以考虑从NTP授时服务器获取,windows的同步网络时间就是从NTP授时服务器获取的。

NTP授时服务器协议采用UDP,端口一般为123,下面给出从github上整理的代码,亲测可用,授时服务器地址选用的是阿里云的公共NTP服务器。

INT64 GetNTPTime()
{
    //初始化网络库
    WSADATA wsaData;
	::WSAStartup(MAKEWORD(2, 2), &wsaData);
    //下面是获取过程
	INT64 curTm = 0;
	struct hostent *host = NULL;
	int nErrno = 0;

	const char *server = "ntp.aliyun.com";
	const char *port = "123";
	ADDRINFOA hints, *res, *ap; /* address info structs */
	socklen_t addrlen = sizeof(struct sockaddr_storage);

	struct ntpPacket{
		UINT8 flags;
		UINT8 stratum;
		UINT8 poll;
		UINT8 precision;
		UINT32 root_delay;
		UINT32 root_dispersion;
		UINT8 referenceID[4];
		UINT32 ref_ts_sec;
		UINT32 ref_ts_frac;
		UINT32 origin_ts_sec;
		UINT32 origin_ts_frac;
		UINT32 recv_ts_sec;
		UINT32 recv_ts_frac;
		UINT32 trans_ts_sec;
		UINT32 trans_ts_frac;
	};
#define ENDIAN_SWAP32(data)  	((data >> 24) | /* right shift 3 bytes */ \
	((data & 0x00ff0000) >> 8) | /* right shift 1 byte */ \
	((data & 0x0000ff00) << 8) | /* left shift 1 byte */ \
	((data & 0x000000ff) << 24)) /* left shift 3 bytes */

	struct ntpPacket packet;
	UINT8 *ptr = (UINT8 *)(&packet); /* to read raw bytes */

	int server_sock; /* send through this socket */
	int error; /* error checking */
	unsigned int recv_secs;

	/* server is required, port is optional */
	memset(&packet, 0, sizeof(struct ntpPacket));
	packet.flags = 0xe3;

	memset(&hints, 0, sizeof(hints));
	hints.ai_socktype = SOCK_DGRAM;

	/* fill our address structs for ntp server */
	error = getaddrinfo(server, port, &hints, &res);
	/* loop through results */
	for (ap = res; ap != NULL; ap = ap->ai_next) {
		server_sock = socket(ap->ai_family, ap->ai_socktype, ap->ai_protocol);
		if (server_sock == -1)
			continue;
		break;
	}
	if (ap == NULL) {
		return curTm;
	}

	error = ::sendto(server_sock, (const char*)&packet, sizeof(struct ntpPacket), 0, ap->ai_addr, addrlen);
	if (error == -1) {
		return curTm;
	}
	error = recvfrom(server_sock, (char*)&packet, sizeof(struct ntpPacket), 0, ap->ai_addr, &addrlen);
	if (error == -1) {
		return curTm;
	}

	freeaddrinfo(res); /* all done */

	/* correct for right endianess */
	packet.recv_ts_sec = ENDIAN_SWAP32(packet.recv_ts_sec);

	/* print date with receive timestamp */
	recv_secs = packet.recv_ts_sec - 2208988800L; /* convert to unix time */
	curTm = recv_secs;
	
	return curTm;
}

代码比较粗糙,比如没有加winsock2.h等头文件,比如没有WSACleanup()等,请使用者根据自己的实际使用情况自行添加和优化

代码我是在win下面跑的,一切正常。linux和unix下,稍微改改也可以跑。

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
获取Windows系统的物理硬盘的读写速度,你可以使用Windows API函数来实现。以下是一个使用C++代码获取硬盘读写速度的示例: ```cpp #include <windows.h> #include <iostream> int main() { ULARGE_INTEGER lastTotalReadBytes; ULARGE_INTEGER lastTotalWriteBytes; FILETIME lastTime; if (!GetSystemTimes(&lastTime, NULL, NULL)) { std::cout << "Failed to get system times." << std::endl; return 1; } if (!GetDiskFreeSpaceEx(NULL, NULL, NULL, &lastTotalWriteBytes)) { std::cout << "Failed to get disk free space." << std::endl; return 1; } while (true) { ULARGE_INTEGER totalReadBytes; ULARGE_INTEGER totalWriteBytes; FILETIME currentTime; if (!GetSystemTimes(&currentTime, NULL, NULL)) { std::cout << "Failed to get system times." << std::endl; return 1; } if (!GetDiskFreeSpaceEx(NULL, NULL, NULL, &totalWriteBytes)) { std::cout << "Failed to get disk free space." << std::endl; return 1; } ULARGE_INTEGER readBytes; readBytes.QuadPart = ((ULONGLONG)totalWriteBytes.QuadPart - (ULONGLONG)lastTotalWriteBytes.QuadPart); ULARGE_INTEGER elapsedTime; elapsedTime.QuadPart = ((ULONGLONG)currentTime.dwLowDateTime - (ULONGLONG)lastTime.dwLowDateTime); double readSpeed = (double)readBytes.QuadPart / (double)elapsedTime.QuadPart * 10000; std::cout << "Disk read speed: " << readSpeed << " bytes/s" << std::endl; lastTotalReadBytes = totalReadBytes; lastTime = currentTime; Sleep(1000); // 每秒更新一次读写速度 } return 0; } ``` 这个示例代码使用了`GetSystemTimes`函数获取系统时间和`GetDiskFreeSpaceEx`函数获取硬盘空闲空间和写入字节数。然后,通过计算两个时间点之间的差异和写入字节数之差,得出硬盘读取速度。 请注意,以上代码只是一个简单示例,仅获取硬盘的写入速度,并在每秒更新一次读取速度。你可以根据自己的需求进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值