94 lines
2.2 KiB
C++
94 lines
2.2 KiB
C++
|
|
#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;
|
|||
|
|
}
|