Elevator/time_sync/time_sync.cpp

217 lines
7.1 KiB
C++
Raw Normal View History

2024-07-28 18:23:29 +08:00
/*
/opt/atk-dlrv1126-toolchain/usr/bin/arm-linux-gnueabihf-g++ -o time_sync time_sync.cpp -lpthread
*/
// #include <iostream>
// #include <cstring>
// #include <ctime>
// #include <iomanip>
// #include <sys/socket.h>
// #include <arpa/inet.h>
// #include <netdb.h>
// #include <unistd.h>
// int main() {
// // 创建套接字
// int socketId = socket(AF_INET, SOCK_STREAM, 0);
// if (socketId == -1) {
// std::cerr << "无法创建套接字" << std::endl;
// return 1;
// }
// // 获取时间服务器的IP地址
// struct hostent* server = gethostbyname("edu.ntp.org.cn");
// if (server == nullptr) {
// std::cerr << "无法解析时间服务器" << std::endl;
// return 1;
// }
// // 配置服务器地址
// struct sockaddr_in serverAddress{};
// serverAddress.sin_family = AF_INET;
// serverAddress.sin_port = htons(13);
// std::memcpy(&serverAddress.sin_addr.s_addr, server->h_addr, server->h_length);
// // 连接到时间服务器
// if (connect(socketId, (struct sockaddr*) &serverAddress, sizeof(serverAddress)) == -1) {
// std::cerr << "无法连接到时间服务器" << std::endl;
// return 1;
// }
// // 从服务器接收时间
// char buffer[128];
// ssize_t bytesRead = recv(socketId, buffer, sizeof(buffer) - 1, 0);
// if (bytesRead == -1) {
// std::cerr << "无法接收数据" << std::endl;
// return 1;
// }
// buffer[bytesRead] = '\0';
// // 输出接收到的时间字符串
// std::cout << "接收到的时间字符串:" << buffer << std::endl;
// // // 解析时间字符串
// // std::tm timeInfo{};
// // std::istringstream iss(buffer);
// // int skipFields;
// // if (!(iss >> skipFields >> std::get_time(&timeInfo, "%d-%m-%y %H:%M:%S"))) {
// // std::cerr << "无法解析时间" << std::endl;
// // return 1;
// // }
// // 解析时间字符串
// int year, month, day, hour, minute, second;
// if (sscanf(buffer, "%*d %d-%d-%d %d:%d:%d",
// &year, &month, &day, &hour, &minute, &second) != 6) {
// std::cerr << "无法解析时间" << std::endl;
// return 1;
// }
// // // 从timeInfo结构中获取时间值
// // int year = timeInfo.tm_year + 1900;
// // int month = timeInfo.tm_mon + 1;
// // int day = timeInfo.tm_mday;
// // int hour = timeInfo.tm_hour;
// // int minute = timeInfo.tm_min;
// // int second = timeInfo.tm_sec;
// // 构建设置系统时间的命令
// char dateCmd[128];
// snprintf(dateCmd, sizeof(dateCmd), "date -s \"%04d-%d-%d %02d:%02d\"",
// year+2000, month, day, hour, minute);
// std::cout << "dateCmd: " << dateCmd << std::endl;
// // 设置系统时间
// if (system(dateCmd) == -1) {
// std::cerr << "无法设置系统时间" << std::endl;
// return 1;
// }
// std::cout << "系统时间已更新" << std::endl;
// // 关闭套接字
// close(socketId);
// return 0;
// }
#include <iostream>
#include <cstring>
#include <ctime>
#include <iomanip>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
int main() {
while(true) {
std::cerr << "开始时间矫正!" << std::endl;
// 创建套接字
int socketId = socket(AF_INET, SOCK_STREAM, 0);
if (socketId == -1) {
std::cerr << "无法创建套接字" << std::endl;
sleep(5);
continue;
}
// 获取时间服务器的IP地址
struct hostent* server = gethostbyname("time.nist.gov"); //微软
// struct hostent* server = gethostbyname("time1.cloud.tencent.com");
if (server == nullptr) {
std::cerr << "无法解析时间服务器" << std::endl;
sleep(5);
continue;
}
// 配置服务器地址
struct sockaddr_in serverAddress{};
serverAddress.sin_family = AF_INET;
serverAddress.sin_port = htons(13);
// serverAddress.sin_port = htons(123);
std::memcpy(&serverAddress.sin_addr.s_addr, server->h_addr, server->h_length);
// 连接到时间服务器
if (connect(socketId, (struct sockaddr*) &serverAddress, sizeof(serverAddress)) == -1) {
std::cerr << "无法连接到时间服务器" << std::endl;
perror("连接时间服务器失败");
sleep(5);
continue;
}
// 从服务器接收时间
char buffer[128];
ssize_t bytesRead = recv(socketId, buffer, sizeof(buffer) - 1, 0);
if (bytesRead == -1) {
std::cerr << "无法接收数据" << std::endl;
sleep(5);
continue;
}
buffer[bytesRead] = '\0';
// 输出接收到的时间字符串
std::cout << "接收到的时间字符串:" << buffer << std::endl;
// 解析时间字符串
int year, month, day, hour, minute, second;
if (sscanf(buffer, "%*d %d-%d-%d %d:%d:%d",
&year, &month, &day, &hour, &minute, &second) != 6) {
std::cerr << "无法解析时间" << std::endl;
sleep(5);
continue;
}
std::cout << "解析后的时间信息:" << std::endl;
std::cout << "年份:" << year << std::endl;
std::cout << "月份:" << month << std::endl;
std::cout << "日期:" << day << std::endl;
std::cout << "小时:" << hour << std::endl;
std::cout << "分钟:" << minute << std::endl;
std::cout << "秒钟:" << second << std::endl;
// 关闭套接字
close(socketId);
// 将时间转换为中国时区
std::tm timeInfo{};
timeInfo.tm_year = year +100;
timeInfo.tm_mon = month - 1;
timeInfo.tm_mday = day;
timeInfo.tm_hour = hour;
timeInfo.tm_min = minute;
timeInfo.tm_sec = second;
// std::time_t utcTime = std::mktime(&timeInfo);
// // 转换为中国时区
// std::tm* localTime = std::gmtime(&utcTime);
// localTime->tm_hour += 8; // 添加8小时表示中国时区偏移
// 转换为time_t类型
std::time_t utcTime = std::mktime(&timeInfo);
// 转换为中国时区
const std::time_t chinaTime = utcTime + 8 * 3600; // 添加8小时的偏移量表示中国时区偏移
// 转换为本地时间
std::tm* localTime = std::localtime(&chinaTime);
// 构建设置系统时间的命令
char dateCmd[128];
snprintf(dateCmd, sizeof(dateCmd), "date -s \"%04d-%02d-%02d %02d:%02d:%02d\"",
localTime->tm_year +1900, localTime->tm_mon + 1, localTime->tm_mday,
localTime->tm_hour, localTime->tm_min, localTime->tm_sec);
std::cout << "dateCmd: " << dateCmd << std::endl;
// 设置系统时间
if (system(dateCmd) == -1) {
std::cerr << "无法设置系统时间" << std::endl;
sleep(5);
continue;
}
std::cout << "系统时间已更新" << std::endl;
break;
}
return 0;
}