SwitchGame/source/Tool/RemoteLogger.cpp

94 lines
2.2 KiB
C++
Raw Normal View History

2025-09-15 11:28:54 +08:00
#include "RemoteLogger.h"
RemoteLogger::RemoteLogger() : sockfd(-1), is_initialized(false)
{
memset(&server_addr, 0, sizeof(server_addr));
server_len = sizeof(server_addr);
}
RemoteLogger::~RemoteLogger()
{
close();
}
bool RemoteLogger::Init(const char *target_ip, unsigned short target_port)
{
// 如果已经初始化,先关闭
if (is_initialized)
{
close();
}
// 创建UDP socket
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0)
{
return false;
}
// 设置服务器地址
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(target_port);
// 转换IP地址
if (inet_pton(AF_INET, target_ip, &server_addr.sin_addr) <= 0)
{
::close(sockfd);
sockfd = -1;
return false;
}
is_initialized = true;
return true;
}
std::string RemoteLogger::format_string(const char *format, va_list vl)
{
// 第一次调用:获取所需缓冲区大小
va_list vl_copy;
va_copy(vl_copy, vl); // 复制 va_list关键避免原 vl 被修改)
int length = vsnprintf(nullptr, 0, format, vl_copy);
va_end(vl_copy); // 释放复制的 va_list
if (length < 0)
{
return "Format error"; // 格式化失败时返回明确信息
}
// 第二次调用:实际格式化字符串
std::vector<char> buffer(length + 1); // 用 vector 自动管理内存
vsnprintf(buffer.data(), buffer.size(), format, vl);
return std::string(buffer.data()); // 直接返回,无需手动移除空字符
}
void RemoteLogger::log(const char *format, ...)
{
va_list vl;
va_start(vl, format);
std::string message = format_string(format, vl);
va_end(vl);
// 先输出到SDL日志
SDL_Log(message.c_str());
if (!is_initialized || sockfd < 0)
return;
// 通过UDP发送
sendto(sockfd, message.c_str(), message.size(), 0,
(struct sockaddr *)&server_addr, server_len);
}
void RemoteLogger::close()
{
if (sockfd >= 0)
{
::close(sockfd);
sockfd = -1;
}
is_initialized = false;
}
// 检查是否已初始化
bool RemoteLogger::isInitialized() const
{
return is_initialized;
}