#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 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; }