Files
H100PowerManger/src/pPowerManger/udpcomm/udpComm.cpp
T
zjk 12f0dee86e 修复:跨线程数据竞争 + 协议字段越界 + UDP 发送失败吞错
- 并发安全:PowerManger 新增 m_stateMutex,保护 m_pmCurrentState /
  m_currentDisBreakerState / m_CcuColCmd / faultCode,并封装
  addFaultCode/clearFaultCodes/getFaultCodes 访问器
- SystemData 新增跨线程读访问器(getDynVoltageLink/getPowerBusStatus/
  getDcdcStatus/getDeviceCommonStatus 等)及配电故障码集合加锁访问
- upmsg buildMsg / httpserver pushSystemData / LowerCommManager 均改为
  持锁快照,避免 listen 线程与 comm 线程撕裂读写
- 修复析构顺序:先删 httpServer 再删其他对象,避免 use-after-free
- 修复 ccuState reserved2 越界读(协议预留 2 字节,结构体仅声明 1),
  修正 coutMsg 中 SOC 门限/功率限制字段打印
- udpComm::sendDisSysCmd 不再吞掉异常,返回 sendMsg 实际结果并记录 ERROR,
  新增 SendDisSysCmdFailsWithoutSocket 单测
- 新增 fullFeeder 全类型 UDP 集成仿真器与 fetch-data/clean-data 脚本,
  .gitignore 补充 SQLite 运行期文件与 fullFeeder 二进制
2026-08-21 11:36:19 +08:00

650 lines
19 KiB
C++

#include "udpComm.h"
#include <iostream>
#include <memory>
udpComm::udpComm()
{
udpScoket = nullptr;
ccuHost = "";
ccuPort = 0;
m_commLogger = nullptr;
}
udpComm::~udpComm() {
if (udpScoket) {
delete udpScoket;
udpScoket = nullptr;
}
}
Checksum udpComm::calculateChecksum(const unsigned char* data, int size)
{
Checksum checksum = 0;
int size_data = size - sizeof(Checksum);
for (int i = 0; i < size_data; i++) {
checksum += data[i];
}
return checksum;
}
Checksum udpComm::calculateChecksum(const unsigned char* data, int dataSize, int checkSize)
{
Checksum checksum = 0;
int size_data = dataSize - checkSize;
for (int i = 0; i < size_data; i++) {
checksum += data[i];
}
return checksum;
}
bool udpComm::getMsgId(char *m, size_t len, unsigned short &id)
{
if (m == NULL || len < sizeof(m_header)) {
return false;
}
m_header h;
h = *reinterpret_cast<m_header *>(m);
// 判断消息是否有效
if (h.start1== DIS_MSG_HEAD1 && h.start2==DIS_MSG_HEAD2)
{
id = h.id;
return true;
}
else if (h.start1==CCU_UDPMSG_START1 && h.start2==CCU_UDPMSG_START2)
{
id = h.id;
return true;
}
else
// sError.push_back("Msg Header errar");
// LOG_F(ERROR, "Msg Header errar start1: %d, start2: %d", h.start1, h.start2);
return false;
}
bool udpComm::getMsgFromBuff(char *m, size_t len, msg_CcuStateFbMsg &s) {
if (m == NULL || len < sizeof(msg_CcuStateFbMsg)) {
sError.push_back("CcuStat Msg length error");
return false;
}
Checksum sum;
msg_CcuStateFbMsg *p;
p = reinterpret_cast<msg_CcuStateFbMsg *>(m);
sum = calculateChecksum((unsigned char*)m, sizeof(msg_CcuStateFbMsg));
if (sum != p->checkCode) {
sError.push_back("CcuStat Msg Check error");
return false;
}
s = *p;
return true;
}
bool udpComm::getMsgFromBuff(char *m, size_t len, msg_CcuSetParmFbMsg &s)
{
if (m == NULL || len < sizeof(msg_CcuSetParmFbMsg)) {
sError.push_back("CcuSetParm Msg length error");
return false;
}
Checksum sum;
msg_CcuSetParmFbMsg *p;
p = reinterpret_cast<msg_CcuSetParmFbMsg *>(m);
sum = calculateChecksum((unsigned char*)m, sizeof(msg_CcuSetParmFbMsg));
if (sum!= p->checkCode) {
sError.push_back("CcuSetParm Msg Check error");
return false;
}
s = *p;
return true;
}
bool udpComm::getMsgFromBuff(char *m, size_t len, msg_disHighVolBusFbMsg &s)
{
if (m == NULL || len < sizeof(msg_disHighVolBusFbMsg)) {
sError.push_back("DisSys HVBus Msg length error");
return false;
}
cChecksum sum;
msg_disHighVolBusFbMsg *p;
p = reinterpret_cast<msg_disHighVolBusFbMsg *>(m);
sum = calculateChecksum((unsigned char*)m, sizeof(msg_disHighVolBusFbMsg), sizeof(cChecksum)) & 0xFF;
if (sum != p->checkCode) {
sError.push_back("DisSys HVBus Msg Check error");
LOG_F(ERROR, "DisSys HVBus Msg Check error sum: %d, source checkCode: %d", sum, p->checkCode);
return false;
}
s = *p;
// cout << s.data.busbarAVoltage << endl;
return true;
}
bool udpComm::getMsgFromBuff(char *m, size_t len, msg_disHighAVolBusFbMsg &s)
{
if (m == NULL || len < sizeof(msg_disHighAVolBusFbMsg)) {
sError.push_back("DisSys HVABus Msg length error");
return false;
}
cChecksum sum;
msg_disHighAVolBusFbMsg *p;
p = reinterpret_cast<msg_disHighAVolBusFbMsg *>(m);
sum = calculateChecksum((unsigned char*)m, sizeof(msg_disHighAVolBusFbMsg), sizeof(cChecksum)) & 0xFF;
if (sum!= p->checkCode) {
sError.push_back("DisSys HVABus Msg Check error");
LOG_F(ERROR, "DisSys HVABus Msg Check error sum: %d, source checkCode: %d", sum, p->checkCode);
return false;
}
s = *p;
return true;
}
bool udpComm::getMsgFromBuff(char *m, size_t len, msg_disLowMainBusFbMsg &s)
{
if (m == NULL || len < sizeof(msg_disLowMainBusFbMsg)) {
sError.push_back("DisSys HVBBus Msg length error");
return false;
}
cChecksum sum;
msg_disLowMainBusFbMsg *p;
p = reinterpret_cast<msg_disLowMainBusFbMsg *>(m);
sum = calculateChecksum((unsigned char*)m, sizeof(msg_disLowMainBusFbMsg), sizeof(cChecksum)) & 0xFF;
if (sum!= p->checkCode) {
sError.push_back("DisSys HVBBus Msg Check error");
LOG_F(ERROR, "DisSys HVBBus Msg Check error sum: %d, source checkCode: %d", sum, p->checkCode);
return false;
}
s = *p;
return true;
}
bool udpComm::getMsgFromBuff(char *m, size_t len, msg_disLowBusFbMsg &s)
{
if (m == NULL || len < sizeof(msg_disLowBusFbMsg)) {
sError.push_back("DisSys LVBus Msg length error");
return false;
}
cChecksum sum;
msg_disLowBusFbMsg *p;
p = reinterpret_cast<msg_disLowBusFbMsg *>(m);
sum = calculateChecksum((unsigned char*)m, sizeof(msg_disLowBusFbMsg), sizeof(cChecksum)) & 0xFF;
if (sum!= p->checkCode) {
sError.push_back("DisSys LVBus Msg Check error");
LOG_F(ERROR, "DisSys LVBus Msg Check error sum: %d, source checkCode: %d", sum, p->checkCode);
return false;
}
s = *p;
return true;
}
bool udpComm::pushMsgToQueue(unsigned char *m, size_t len)
{
if(m==NULL || len < sizeof(m_header))
{
// sError.push_back("pushMsgToQueue faile,Msg is NULL");
LOG_F(ERROR, "pushMsgToQueue faile,Msg is NULL or too short m: %p len: %zu", m, len);
return false;
}
unsigned char* Buff = m;
//消息头鉴定
unsigned short id;
if(!getMsgId((char *)Buff, len, id))
{
return false;
}
//输入消息
switch (id)
{
case CCU_STATE_FB_ID: //CCU_STATE_FB 0x0051
{
msg_CcuStateFbMsg s;
if(getMsgFromBuff((char *)Buff, len, s))
{
if (m_commLogger) m_commLogger->onFrame(0, id, "ccuState", Buff, sizeof(msg_CcuStateFbMsg), true);
std::lock_guard<std::mutex> lock(m_mutexCcuState);
if(m_qReceiveCcuStateBuffer.size()<QUENUE_SIZE)
{
double time = MOOSTime(false);
m_qReceiveCcuStateBuffer.push(std::make_pair(time, s));
}
else
{
// sError.push_back("pushMsgToQueue faile,CcuState buffer is full");
LOG_F(INFO, "pushMsgToQueue faile,CcuState buffer is full");
return false;
}
}
else
{
return false;
}
break;
}
case CCU_SET_PARM_FB_ID: //CCU_SET_PARM_FB 0x0040
{
msg_CcuSetParmFbMsg s;
if(getMsgFromBuff((char *)Buff, len, s))
{
if (m_commLogger) m_commLogger->onFrame(0, id, "ccuSetParmFb", Buff, sizeof(msg_CcuSetParmFbMsg), true);
std::lock_guard<std::mutex> lock(m_mutexCcuSetParm);
if(m_qReceiveCcuSetParmBuffer.size()<QUENUE_SIZE)
{
double time = MOOSTime(false);
m_qReceiveCcuSetParmBuffer.push(std::make_pair(time, s));
}
else
{
// sError.push_back("pushMsgToQueue faile,CcuSetParm buffer is full");
LOG_F(INFO, "pushMsgToQueue faile,CcuSetParm buffer is full");
return false;
}
}
else
{
return false;
}
break;
}
case DIS_HVBUS_FB_ID: //DIS_HVBUS_FB 0x0020
{
msg_disHighVolBusFbMsg s;
if(getMsgFromBuff((char *)Buff, len, s))
{
if (m_commLogger) m_commLogger->onFrame(0, id, "disHighVolBusState", Buff, sizeof(msg_disHighVolBusFbMsg), true);
std::lock_guard<std::mutex> lock(m_mutexDisHighVolBus);
if(m_qReceiveDisHighVolBusBuffer.size()<QUENUE_SIZE)
{
double time = MOOSTime(false);
m_qReceiveDisHighVolBusBuffer.push(std::make_pair(time, s));
}
else
{
// sError.push_back("pushMsgToQueue faile,DisSysHVBus buffer is full");
LOG_F(INFO, "pushMsgToQueue faile,DisSysHVBus buffer is full");
return false;
}
}
else
{
return false;
}
break;
}
case DIS_HVBUSA_FB_ID: //DIS_HVBUSA_FB 0x0006
{
msg_disHighAVolBusFbMsg s;
if(getMsgFromBuff((char *)Buff, len, s))
{
if (m_commLogger) m_commLogger->onFrame(0, id, "disHighAVolBusState", Buff, sizeof(msg_disHighAVolBusFbMsg), true);
std::lock_guard<std::mutex> lock(m_mutexDisHighAVolBus);
if(m_qReceiveDisHighAVolBusBuffer.size()<QUENUE_SIZE)
{
double time = MOOSTime(false);
m_qReceiveDisHighAVolBusBuffer.push(std::make_pair(time, s));
}
else
{
// sError.push_back("pushMsgToQueue faile,DisSysHVABus buffer is full");
LOG_F(INFO, "pushMsgToQueue faile,DisSysHVABus buffer is full");
return false;
}
}
else
{
return false;
}
break;
}
case DIS_HVBUSB_FB_ID: //DIS_HVBUSB_FB 0x0007
{
msg_disLowMainBusFbMsg s;
if(getMsgFromBuff((char *)Buff, len, s))
{
if (m_commLogger) m_commLogger->onFrame(0, id, "disLowMainBusState", Buff, sizeof(msg_disLowMainBusFbMsg), true);
std::lock_guard<std::mutex> lock(m_mutexDisHighBVolBus);
if(m_qReceiveDisHighBVolBusBuffer.size()<QUENUE_SIZE)
{
double time = MOOSTime(false);
m_qReceiveDisHighBVolBusBuffer.push(std::make_pair(time, s));
}
else
{
// sError.push_back("pushMsgToQueue faile,DisSysHVBBus buffer is full");
LOG_F(INFO, "pushMsgToQueue faile,DisSysHVBBus buffer is full");
return false;
}
}
else
{
return false;
}
break;
}
case DIS_LVBUS_FB_ID: //DIS_LVBUS_FB 0x0008
{
msg_disLowBusFbMsg s;
if(getMsgFromBuff((char *)Buff, len, s))
{
if (m_commLogger) m_commLogger->onFrame(0, id, "disLowBusState", Buff, sizeof(msg_disLowBusFbMsg), true);
std::lock_guard<std::mutex> lock(m_mutexDisLowBus);
if(m_qReceiveDisLowBusBuffer.size()<QUENUE_SIZE)
{
double time = MOOSTime(false);
m_qReceiveDisLowBusBuffer.push(std::make_pair(time, s));
}
else
{
// sError.push_back("pushMsgToQueue faile,DisSysLVBus buffer is full");
LOG_F(INFO, "pushMsgToQueue faile,DisSysLVBus buffer is full");
return false;
}
}
else
{
return false;
}
break;
}
default:
break;
}
return true;
}
bool udpComm::clearMsgQueue()
{
{
std::lock_guard<std::mutex> lock(m_mutexCcuState);
while(!m_qReceiveCcuStateBuffer.empty())
m_qReceiveCcuStateBuffer.pop();
}
{
std::lock_guard<std::mutex> lock(m_mutexCcuSetParm);
while(!m_qReceiveCcuSetParmBuffer.empty())
m_qReceiveCcuSetParmBuffer.pop();
}
{
std::lock_guard<std::mutex> lock(m_mutexDisHighVolBus);
while(!m_qReceiveDisHighVolBusBuffer.empty())
m_qReceiveDisHighVolBusBuffer.pop();
}
{
std::lock_guard<std::mutex> lock(m_mutexDisHighAVolBus);
while(!m_qReceiveDisHighAVolBusBuffer.empty())
m_qReceiveDisHighAVolBusBuffer.pop();
}
{
std::lock_guard<std::mutex> lock(m_mutexDisHighBVolBus);
while(!m_qReceiveDisHighBVolBusBuffer.empty())
m_qReceiveDisHighBVolBusBuffer.pop();
}
{
std::lock_guard<std::mutex> lock(m_mutexDisLowBus);
while(!m_qReceiveDisLowBusBuffer.empty())
m_qReceiveDisLowBusBuffer.pop();
}
return true;
}
bool udpComm::popMsgFormQueue(double &time,msg_CcuStateFbMsg &m)
{
std::lock_guard<std::mutex> lock(m_mutexCcuState);
if(m_qReceiveCcuStateBuffer.empty())
return false;
time = m_qReceiveCcuStateBuffer.front().first;
m = m_qReceiveCcuStateBuffer.front().second;
m_qReceiveCcuStateBuffer.pop();
return true;
}
bool udpComm::popMsgFormQueue(double &time,msg_CcuSetParmFbMsg &m)
{
std::lock_guard<std::mutex> lock(m_mutexCcuSetParm);
if(m_qReceiveCcuSetParmBuffer.empty())
return false;
time = m_qReceiveCcuSetParmBuffer.front().first;
m = m_qReceiveCcuSetParmBuffer.front().second;
m_qReceiveCcuSetParmBuffer.pop();
return true;
}
bool udpComm::popMsgFormQueue(double &time,msg_disHighVolBusFbMsg &m)
{
std::lock_guard<std::mutex> lock(m_mutexDisHighVolBus);
if(m_qReceiveDisHighVolBusBuffer.empty())
return false;
time = m_qReceiveDisHighVolBusBuffer.front().first;
m = m_qReceiveDisHighVolBusBuffer.front().second;
m_qReceiveDisHighVolBusBuffer.pop();
return true;
}
bool udpComm::popMsgFormQueue(double &time,msg_disHighAVolBusFbMsg &m)
{
std::lock_guard<std::mutex> lock(m_mutexDisHighAVolBus);
if(m_qReceiveDisHighAVolBusBuffer.empty())
return false;
time = m_qReceiveDisHighAVolBusBuffer.front().first;
m = m_qReceiveDisHighAVolBusBuffer.front().second;
m_qReceiveDisHighAVolBusBuffer.pop();
return true;
}
bool udpComm::popMsgFormQueue(double &time,msg_disLowMainBusFbMsg &m)
{
std::lock_guard<std::mutex> lock(m_mutexDisHighBVolBus);
if(m_qReceiveDisHighBVolBusBuffer.empty())
return false;
time = m_qReceiveDisHighBVolBusBuffer.front().first;
m = m_qReceiveDisHighBVolBusBuffer.front().second;
m_qReceiveDisHighBVolBusBuffer.pop();
return true;
}
bool udpComm::popMsgFormQueue(double &time,msg_disLowBusFbMsg &m)
{
std::lock_guard<std::mutex> lock(m_mutexDisLowBus);
if(m_qReceiveDisLowBusBuffer.empty())
return false;
time = m_qReceiveDisLowBusBuffer.front().first;
m = m_qReceiveDisLowBusBuffer.front().second;
m_qReceiveDisLowBusBuffer.pop();
return true;
}
bool udpComm::sendDisSysCmd(const disHighVolBusCmd cmd)
{
unsigned char* msgBuf;
cChecksum cc;
msg_disHVBCmd* msg = new msg_disHVBCmd;
msg->header.id = DIS_HVBUS_CMD_ID;
msg->header.start1 = DIS_MSG_HEAD1;
msg->header.start2 = DIS_MSG_HEAD2;
//TODO : 阈字节长度固定了,后续会修改
msg->header.length = 18;
// msg->header.length = sizeof(disHighVolBusCmd);
msg->data = cmd;
msgBuf = reinterpret_cast<unsigned char *>(msg);
cc = calculateChecksum(msgBuf,sizeof(msg_disHVBCmd),sizeof(cChecksum));
msg->checkCode = cc;
bool sendResult = sendMsg(msgBuf, sizeof(msg_disHVBCmd));
if (!sendResult) {
LOG_F(ERROR, "sendDisSysCmd(disHighVolBusCmd) send failed");
}
if (m_commLogger) m_commLogger->onFrame(1, DIS_HVBUS_CMD_ID, "disHighVolBusCmd", msgBuf, sizeof(msg_disHVBCmd), true);
delete msg;
return sendResult;
}
bool udpComm::sendDisSysCmd(const disHighAVolBusCmd cmd)
{
unsigned char* msgBuf;
cChecksum cc;
msg_disHVBACmd* msg = new msg_disHVBACmd;
msg->header.id = DIS_HVBUSA_CMD_ID;
msg->header.start1 = DIS_MSG_HEAD1;
msg->header.start2 = DIS_MSG_HEAD2;
//TODO : 阈字节长度固定了,后续会修改
msg->header.length = 6;
// msg->header.length = sizeof(disHighAVolBusCmd);
msg->data = cmd;
msgBuf = reinterpret_cast<unsigned char *>(msg);
cc = calculateChecksum(msgBuf,sizeof(msg_disHVBACmd),sizeof(cChecksum));
msg->checkCode = cc;
bool sendResult = sendMsg(msgBuf, sizeof(msg_disHVBACmd));
if (!sendResult) {
LOG_F(ERROR, "sendDisSysCmd(disHighAVolBusCmd) send failed");
}
if (m_commLogger) m_commLogger->onFrame(1, DIS_HVBUSA_CMD_ID, "disHighAVolBusCmd", msgBuf, sizeof(msg_disHVBACmd), true);
delete msg;
return sendResult;
}
bool udpComm::sendDisSysCmd(const disHighBVolBusCmd cmd)
{
unsigned char* msgBuf;
cChecksum cc;
msg_disHVBBCmd* msg = new msg_disHVBBCmd;
msg->header.id = DIS_HVBUSB_CMD_ID;
msg->header.start1 = DIS_MSG_HEAD1;
msg->header.start2 = DIS_MSG_HEAD2;
//TODO : 阈字节长度固定了,后续会修改
msg->header.length = 8;
// msg->header.length = sizeof(disHighBVolBusCmd);
msg->data = cmd;
msgBuf = reinterpret_cast<unsigned char *>(msg);
cc = calculateChecksum(msgBuf,sizeof(msg_disHVBBCmd),sizeof(cChecksum));
msg->checkCode = cc;
bool sendResult = sendMsg(msgBuf, sizeof(msg_disHVBBCmd));
if (!sendResult) {
LOG_F(ERROR, "sendDisSysCmd(disHighBVolBusCmd) send failed");
}
if (m_commLogger) m_commLogger->onFrame(1, DIS_HVBUSB_CMD_ID, "disLowMainBusCmd", msgBuf, sizeof(msg_disHVBBCmd), true);
delete msg;
return sendResult;
}
bool udpComm::sendDisSysCmd(const disLowBusCmd cmd)
{
unsigned char* msgBuf;
cChecksum cc;
msg_disLVBCmd* msg = new msg_disLVBCmd;
msg->header.id = DIS_LVBUS_CMD_ID;
msg->header.start1 = DIS_MSG_HEAD1;
msg->header.start2 = DIS_MSG_HEAD2;
//TODO : 阈字节长度固定了,后续会修改
msg->header.length = 8;
// msg->header.length = sizeof(disLowBusCmd);
msg->data = cmd;
msgBuf = reinterpret_cast<unsigned char *>(msg);
cc = calculateChecksum(msgBuf,sizeof(msg_disLVBCmd),sizeof(cChecksum));
// msg->checkCode = static_cast<cChecksum>(cc & 0xFF);
msg->checkCode = cc;
bool sendResult = sendMsg(msgBuf, sizeof(msg_disLVBCmd));
if (!sendResult) {
LOG_F(ERROR, "sendDisSysCmd(disLowBusCmd) send failed");
}
if (m_commLogger) m_commLogger->onFrame(1, DIS_LVBUS_CMD_ID, "disLowBusCmd", msgBuf, sizeof(msg_disLVBCmd), true);
delete msg;
return sendResult;
}
bool udpComm::sendCcuColCmd(const ccuColCmd cmd)
{
unsigned char* msgBuf;
Checksum cc;
msg_CcuColCmdMsg* msg = new msg_CcuColCmdMsg();
memset(msg, 0, sizeof(msg_CcuColCmdMsg)); // 初始化所有字段为0
msg->header.id = CCU_CMD_ID;
msg->header.start1 = CCU_UDPMSG_START1;
msg->header.start2 = CCU_UDPMSG_START2;
msg->header.length = sizeof(ccuColCmd);
// 确保日期获取成功
if(!getDate(msg->date.year,msg->date.month,msg->date.day,
msg->date.hour,msg->date.minute,msg->date.second,msg->date.milliseconds)) {
LOG_F(ERROR, "Failed to get current date/time");
delete msg;
return false;
}
msg->cmd = cmd;
msgBuf = reinterpret_cast<unsigned char *>(msg);
cc = calculateChecksum(msgBuf,sizeof(msg_CcuColCmdMsg));
msg->checkCode = static_cast<cChecksum>(cc & 0xFF);
bool sendResult = false;
try {
sendResult = sendMsg(msgBuf,sizeof(msg_CcuColCmdMsg));
if (!sendResult) {
LOG_F(ERROR, "Failed to send CCU command");
}
} catch (const std::exception& e) {
LOG_F(ERROR, "Exception in sendCcuColCmd: %s", e.what());
}
if (m_commLogger) m_commLogger->onFrame(1, CCU_CMD_ID, "ccuColCmd", msgBuf, sizeof(msg_CcuColCmdMsg), true);
delete msg;
return sendResult;
}
bool udpComm::sendCcuSetParmCmd(const ccuSetParmCmd cmd)
{
unsigned char* msgBuf;
Checksum cc;
msg_CcuSetParmMsg* msg = new msg_CcuSetParmMsg;
msg->header.id = CCU_SET_PARM_ID;
msg->header.start1 = CCU_UDPMSG_START1;
msg->header.start2 = CCU_UDPMSG_START2;
msg->header.length = sizeof(ccuSetParmCmd);
msg->cmd = cmd;
msgBuf = reinterpret_cast<unsigned char *>(msg);
cc = calculateChecksum(msgBuf,sizeof(msg_CcuSetParmMsg));
msg->checkCode = static_cast<cChecksum>(cc & 0xFF);
try
{
sendMsg(msgBuf,sizeof(msg_CcuSetParmMsg));
}
catch(const std::exception& e)
{
std::cerr << e.what() << '\n';
}
if (m_commLogger) m_commLogger->onFrame(1, CCU_SET_PARM_ID, "ccuSetParmCmd", msgBuf, sizeof(msg_CcuSetParmMsg), true);
delete msg;
return true;
}
bool udpComm::getDate(unsigned short &year, unsigned char &month, unsigned char &day, unsigned char &hour, unsigned char &minute, unsigned char &second, unsigned char &milliseconds) {
// 获取当前时间
std::time_t now = std::time(nullptr);
if (now == -1) {
return false; // 获取时间失败
}
// 转换为本地时间
std::tm *localTime = std::localtime(&now);
if (!localTime) {
return false; // 转换失败
}
// 获取年、月、日、时、分、秒
year = localTime->tm_year + 1900; // tm_year 是从 1900 年开始的
month = localTime->tm_mon + 1; // tm_mon 是从 0 开始的,0 对应 1 月
day = localTime->tm_mday;
hour = localTime->tm_hour;
minute = localTime->tm_min;
second = localTime->tm_sec;
// 获取毫秒,使用 std::chrono
auto now_ms = std::chrono::system_clock::now();
auto duration = now_ms.time_since_epoch();
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count() % 1000; // 取毫秒部分
ms = ms/10;
milliseconds = static_cast<unsigned char>(ms);
return true;
}