ZBLOG

Glog基于udp实现,给出完整的封装代码并测试

Glog 基于 UDP 的封装实现

下面是一个基于 UDP 协议实现的简单日志库(Glog-like)的完整代码,包含测试示例。

1. 头文件 udp_logger.h

#ifndef UDP_LOGGER_H
#define UDP_LOGGER_H

#include <string>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>
#include <ctime>
#include <sstream>

class UdpLogger {
public:
    enum Severity {
        INFO,
        WARNING,
        ERROR,
        FATAL
    };

    // 构造函数,指定目标IP和端口
    UdpLogger(const std::string& ip, int port);
    
    // 析构函数
    ~UdpLogger();
    
    // 日志记录函数
    void Log(Severity severity, const std::string& message);
    
    // 便捷方法
    void Info(const std::string& message);
    void Warning(const std::string& message);
    void Error(const std::string& message);
    void Fatal(const std::string& message);

private:
    int sockfd_;
    struct sockaddr_in server_addr_;
    
    // 获取当前时间字符串
    std::string GetCurrentTime();
    
    // 获取严重级别字符串
    std::string GetSeverityString(Severity severity);
};

#endif // UDP_LOGGER_H

2. 实现文件 udp_logger.cpp

#include "udp_logger.h"
#include <iostream>

UdpLogger::UdpLogger(const std::string& ip, int port) {
    // 创建UDP套接字
    sockfd_ = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (sockfd_ == -1) {
        perror("Failed to create socket");
        exit(EXIT_FAILURE);
    }
    
    // 设置服务器地址结构体
	memset(&server_addr_, 0, sizeof(server_addr_));
	server_addr_.sin_family = AF_INET;
	server_addr_.sin_port = htons(port);
	
	if (inet_pton(AF_INET, ip.c_str(), &server_addr_.sin_addr) <= 0) {
		perror("Invalid address/Address not supported");
		close(sockfd_); 
		exit(EXIT_FAILURE);
	}
}

UdpLogger::~UdpLogger() {
	if (sockfd_ != -1) {
		close(sockfd_); 
	}
}

std::string UdpLogger::GetCurrentTime() {
	std::time_t now = time(nullptr); 
	std::tm* tm_now = localtime(&now); 
	
	char buffer[80]; 
	strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", tm_now); 
	return buffer; 
}

std::string UdpLogger::GetSeverityString(Severity severity) { 
	switch (severity) { 
	case INFO: return "INFO"; 
	case WARNING: return "WARNING"; 
	case ERROR: return "ERROR"; 
	case FATAL: return "FATAL"; 
	default: return "UNKNOWN"; } }

void UdpLogger::Log(Severity severity, const std::string& message) {  
	std::ostringstream oss;  
	
	oss << "[" << GetCurrentTime() << "] [" << GetSeverityString(severity) << "] "
	    << message;
	
	std::string log_message = oss.str();  
	
	int ret = sendto(sockfd_, log_message.c_str(), log_message.size(), MSG_CONFIRM,
				   (const struct sockaddr*)&server_addr_, sizeof(server_addr_));  
				   
	if (ret == -1) {  
	    perror("Failed to send log");  
	    close(sockfd_);  
	    exit(EXIT_FAILURE); } }

void UdpLogger::Info(const std::string& message) { Log(INFO, message); }
void UdpLogger::Warning(const std :: string &message ){ Log(WARNING ,message );}  
void UdpLogger ::Error(const std :: string &message ){ Log(ERROR ,message );}  
void UdpLogger ::Fatal(const std :: string &message ){ Log(FATAL ,message );}

3. UDP日志接收服务器 udp_log_server.cpp

#include <iostream> #include<sys/socket.h> #include<netinet/in.h> #include<arpa/inet.h> #include<unistd.h> #include<cstring>

#define BUFFER_SIZE  1024 

int main(int argc ,char **argv){  

	if(argc !=2){ printf("Usage :%s [port]\n",argv[0]); exit(-1);}  

	int port=atoi(argv[1]);  

	int sock=socket(AF_INET,SOCK_DGRAM ,IPPROTO_UDP );  

	struct sockaddr_in addr={}; memset(&addr,'\0',sizeof(struct sockaddr_in)); addr.sin_family=AF_INET ; addr.sin_port=htons((unsigned short)(port)) ; addr.sin_addr.s_addr=htonl(INADDR_ANY ) ; bind(sock,(struct sockaddr *) &addr,sizeof(struct sockaddr_in )) ;  

	char buf[BUFFER_SIZE ]={}; while(true){ struct sockaddr_in client={}; memset(&client,'\0',sizeof(client )) ; unsigned len=sizeof(client )) ; recvfrom(sock,buf,BUFFER_SIZE-1,NULL,(struct sockaddrr *) &client,&len )) ;

	printf("%s\n",buf );
	memset(buf,'\0',BUFFER_SIZE )) ;
	sleep(.5f );
}}//end main()

##4.测试程序 test.cpp

# include"udplogger.hpp"
# include<iostream >
using namespace st d;

intmain(){ try{
     /*创建logger实例*/     
     UpdLoggerglogger ("127 .0 .0 .1 ",9999 );

     /*发送不同级别的日志*/
      g logger.Informational ("This is an informational messag e." );
      g logger.Warning ("This is a warning messag e." );
      g logger.Error ("This is an error messag e." );
      g logger.Fatal ("This is a fatal messag e." );

      cout<<"All logs sent successfully!"<<endl ;

}catch(... ){
      cerr<<"Exception occurred while sending logs!"<<endl ;
return-10 ;
}//end try-catch block.

return00 ;
}//end main function.

##5.Makefile文件内容如下:

all : server client test clean run_server run_client run_test 

run_server :
./udpserver.exe &

run_client :
./testclient.exe &

run_test :
./testapp.exe &

clean :
rm-rf *.o *.exe *~

%.o : %. cpp $(CXX)-c$<-o$@ $(CFLAGS )

udpserver.exe : udpserver.o $(CXX)$^-o$@ $(LDFLAGS )

testclient.exe : testclient.o updlogger.o $(CXX)$^-o$@ $(LDFLAGS )

testapp.exe : testapp.o updlogger.o $(CXX)$^-o$@ $(LDFLAGS )

##6.编译运行步骤说明:

###6.1编译并启动服务端程序:

g++ -std=c++11 -Wall -pedantic errors.cpp -o errors && ./errors &

或者直接执行:

make run_server PORT=9999 &

其中PORT参数可以修改为你想要监听的端口号。

###6.2编译并启动客户端程序:

g++ --std=c++11 --Wall --pedantic testclient.cpp updlogger.cpp – o testclient && ./testclien t…

或者直接执行:

make run_clien t…

###6.3查看输出结果: 服务端会打印出类似以下格式的内容: “[2023-03-15T14:25:36] [INFO] Thisisaninformationalmessage.” “[2023–03–15T14:25:36][WARNI NG] Thisisawarningmessage.” “[2023–03–15T14:25:36][ERRO R] Thisisanerrormessage.” “[2023–03–15T14:25:36][FATA L] Thisisafatalmessage.”

注意事项: •需要确保网络连接正常且防火墙允许指定端口通信。 •实际生产环境中应考虑添加错误处理机制、日志缓冲队列等优化措施。 •本示例仅用于演示基本原理,请根据实际需求进行扩展完善。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://sdn.0voice.com/?id=8034

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?