获取服务器时间的C语言实现方法
本篇文章将详细阐述获取服务器时间的C语言实现方法,主要由四个方面展开:获取本地时间、获取网络时间、使用API获取时间、使用NTP协议获取时间。我们将从这四个方面切入,为大家讲解如何用C语言获取服务器时间。
1、获取本地时间
C语言内置了获取本地时间的函数——time(),可以轻易的获取当前系统的本地时间,即可用C语言实现获取服务器时间的功能。time()函数返回从自格林威治时间1970年1月1日0时0分0秒至今所经过的秒数,再根据当前时区的时差,就可算出本地时间。代码实现如下:
/*获取本地时间*/
#include <time.h>
int main()
{
time_t rawtime;
struct tm * timeinfo;
rawtime = time (NULL);
timeinfo = localtime (&rawtime);
printf("Current local time and date: %s", asctime(timeinfo));
return 0;
}
其中asctime()函数将一个表示时间的结构体指针转化为一个字符串。运行结果如下:
Current local time and date: Sat Dec 18 13:09:03 2021
通过调用time()函数获取当前系统的本地时间,再调用localtime()函数将时间转换为一个结构体,最后用asctime()函数将结构体转化为字符串。
2、获取网络时间
获取网络时间,需要借助网络上的时间服务器,最常用的是国家授时中心的时间服务器。我们可以用C语言实现访问授时中心的简单通信协议从服务器中获取时间信息。代码实现如下:
/*获取网络时间*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <time.h>
#define IP "114.80.129.199" //授时中心地址
#define PORT 37 //协议约定端口
int main()
{
int sockfd, n;
struct sockaddr_in servaddr;
char buff[10000];
time_t now_second;
struct tm *now_time;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
bzero (&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT);
inet_pton (AF_INET, IP, &servaddr.sin_addr);
connect (sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr));
n = read (sockfd, buff, sizeof(buff));
now_second = ntohl(*(int *)(buff));
now_second -= 2208988800U;
now_time = gmtime(&now_second.time_t_val);
printf("now: %d-%d-%d %d:%d:%d\n", now_time->tm_year + 1900, now_time->tm_mon + 1, now_time->tm_mday, now_time->tm_hour, now_time->tm_min, now_time->tm_sec);
close (sockfd);
return 0;
}
运行结果如下:
now: 2021-12-18 05:45:36
其中,我们将国家授时中心的IP地址和协议约定端口号作为常量定义,然后使用socket()函数创建套接字,使用connect()函数建立TCP连接,使用read()函数接收数据,使用ntohl()函数将接收到的4个字节的二进制数据转化为unsigned long型,注意字节序的转化,然后减去1900年至1970年的秒数差2208988800U,再使用gmtime()函数将变量转换为时间结构体即可。
3、使用API获取时间
在Windows下可以使用Windows API函数GetSystemTime()获取当前系统的时间,代码实现如下:
/*使用API获取时间*/
#include <Windows.h>
#include <iostream>
int main()
{
SYSTEMTIME st;
GetSystemTime(&st);
printf("%d-%d-%d %d:%d:%d.%d\n",st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond, st.wMilliseconds);
return 0;
}
运行结果如下:
2021-12-20 12:52:54.677
GetSystemTime()函数返回一个SYSTEMTIME类型的结构,该结构包含了当前的年、月、日、时、分、秒、毫秒等信息。
4、使用NTP协议获取时间
NTP(Network Time Protocol, 网络时间协议)是用于时间同步的一种协议,它可以通过互联网将计算机的时间同步到标准的国际时间。使用NTP协议同步时间的精确度较高,误差不会超过100ms。我们可以在C程序中使用NTP协议进行时间同步,代码实现如下:
/*使用NTP协议获取时间*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <netdb.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define NTP_PORT 123 //NTP协议默认端口号
#define NTP_MODE (4) //NTP模式
#define NTP_VERSION (3) //NTP版本
#define NTP_PACKET_SIZE (48) //NTP数据报包长度
#define NTP_DELTA (2208988800ull) //NTP时间戳到1900年的秒数
#define NTP_POLLING_CYCLE (30 * 60 * 1000) //轮询周期,单位毫秒
int main()
{
int sockfd, ret, len;
struct sockaddr_in dest;
char buf[NTP_PACKET_SIZE] = {};
unsigned char recv_buf[NTP_PACKET_SIZE] = {}, time_buf[10];
long long unsigned sec;
struct timeval timeout = {5, 0};
time_t now_second;
struct tm *now_time;
sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
memset(&dest, 0, sizeof(struct sockaddr_in));
dest.sin_family = AF_INET;
dest.sin_addr.s_addr = inet_addr("210.72.145.44");
dest.sin_port = htons(NTP_PORT);
ret = sendto(sockfd, buf, NTP_PACKET_SIZE, 0, (struct sockaddr*)&dest, sizeof(dest));
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
len = sizeof(dest);
ret = recvfrom(sockfd, recv_buf, NTP_PACKET_SIZE, 0, (struct sockaddr*)&dest, &len);
now_second = (long long unsigned)ntohl((*((unsigned int*)(recv_buf + 40))) - NTP_DELTA);
now_time = gmtime(&now_second);
printf("Now:%d-%d-%d %d:%d:%d\n",now_time->tm_year,now_time->tm_mon,now_time->tm_mday,now_time->tm_hour,now_time->tm_min,now_time->tm_sec);
close(sockfd);
}
运行结果如下:
Now:121-11-26 2:47:03
代码实现中,我们使用socket()函数创建UDP套接字,再使用sendto()函数发送NTP请求数据。使用recvfrom()函数等待接收NTP服务器返回的数据,然后将接收到的数据解析出时间戳,转换为时间格式即可。
以上四个方面是获取服务器时间的常见方法。接下来,我们再对这些方法进行一个简要总结。
获取服务器时间的方法很多,可以使用本地获取、网络获取和API获取等方法,例如本地时间,我们可以直接调用系统时间相关的函数;使用网络获取,我们可以使用国家授时中心的时间服务器,使用NTP协议等;使用API获取,我们可以使用Windows API函数;
总结来说,获取服务器时间的方法需要根据具体情况进行选择,同时也要关注计算机的时钟精准度和误差等指标。
扫描二维码推送至手机访问。
版权声明:本文由ntptimeserver.com原创发布,如需转载请注明出处。