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