97色伦色在线综合视频,无玛专区,18videosex性欧美黑色,日韩黄色电影免费在线观看,国产精品伦理一区二区三区,在线视频欧美日韩,亚洲欧美在线中文字幕不卡

開源公司網(wǎng)站福州網(wǎng)絡(luò)科技公司有哪些

鶴壁市浩天電氣有限公司 2026/01/24 08:50:56
開源公司網(wǎng)站,福州網(wǎng)絡(luò)科技公司有哪些,做網(wǎng)站優(yōu)化的工資有多高,小程序外包多少錢基于C的UDP網(wǎng)絡(luò)通信系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn) 前言 在網(wǎng)絡(luò)編程領(lǐng)域#xff0c;UDP#xff08;User Datagram Protocol#xff0c;用戶數(shù)據(jù)報(bào)協(xié)議#xff09;作為一種無(wú)連接的傳輸層協(xié)議#xff0c;以其高效、低延遲的特性在實(shí)時(shí)性要求高的應(yīng)用場(chǎng)景中占據(jù)重要地位。與TCP協(xié)議相比的UDP網(wǎng)絡(luò)通信系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)前言在網(wǎng)絡(luò)編程領(lǐng)域UDPUser Datagram Protocol用戶數(shù)據(jù)報(bào)協(xié)議作為一種無(wú)連接的傳輸層協(xié)議以其高效、低延遲的特性在實(shí)時(shí)性要求高的應(yīng)用場(chǎng)景中占據(jù)重要地位。與TCP協(xié)議相比UDP不需要建立連接不保證數(shù)據(jù)包的順序和可靠性但正是這種輕量級(jí)特性使其在視頻流、在線游戲、DNS查詢等領(lǐng)域得到廣泛應(yīng)用。本文將深入探討如何從零開始構(gòu)建一個(gè)完整的UDP通信系統(tǒng)涵蓋服務(wù)器端、客戶端的設(shè)計(jì)與實(shí)現(xiàn)包括套接字編程的核心概念、關(guān)鍵系統(tǒng)調(diào)用、錯(cuò)誤處理機(jī)制以及實(shí)際應(yīng)用中的注意事項(xiàng)。通過本文的學(xué)習(xí)讀者不僅能夠掌握UDP網(wǎng)絡(luò)編程的基本技能還能深入理解網(wǎng)絡(luò)通信的底層原理。本文實(shí)現(xiàn)的UDP通信系統(tǒng)具有以下特點(diǎn)完整的服務(wù)器/客戶端架構(gòu)詳細(xì)的錯(cuò)誤處理和日志記錄可配置的服務(wù)器參數(shù)跨平臺(tái)兼容性考慮豐富的代碼示例和詳細(xì)注釋一、UDP服務(wù)器UdpServer.hpp1.1 基本框架設(shè)計(jì)UDP服務(wù)器的設(shè)計(jì)需要遵循模塊化、可擴(kuò)展的原則。我們將服務(wù)器封裝為一個(gè)類包含初始化、運(yùn)行和清理等基本功能。#ifndefUDPSERVER_HPP#defineUDPSERVER_HPP#includeiostream#includestring#includecstring#includecstdlib#includeunistd.h#includearpa/inet.h#includesys/socket.h#includesys/types.h#includenetinet/in.h#includethread#includevector#includememory#includeatomic#includefunctional#includeLog.hppclassUdpServer{private:intport_;// 服務(wù)器端口intsockfd_;// 套接字描述符std::atomicboolis_running_;// 服務(wù)器運(yùn)行狀態(tài)structsockaddr_inserver_addr_;// 服務(wù)器地址結(jié)構(gòu)structsockaddr_inclient_addr_;// 客戶端地址結(jié)構(gòu)socklen_t client_addr_len_;// 客戶端地址長(zhǎng)度// 服務(wù)器配置參數(shù)size_t buffer_size_;// 緩沖區(qū)大小inttimeout_sec_;// 接收超時(shí)時(shí)間(秒)inttimeout_usec_;// 接收超時(shí)時(shí)間(微秒)boolreuse_addr_;// 是否重用地址public:// 構(gòu)造函數(shù)explicitUdpServer(intport8080);// 析構(gòu)函數(shù)~UdpServer();// 禁止拷貝構(gòu)造和賦值UdpServer(constUdpServer)delete;UdpServeroperator(constUdpServer)delete;// 初始化服務(wù)器boolInit();// 運(yùn)行服務(wù)器voidRun();// 停止服務(wù)器voidStop();// 設(shè)置配置參數(shù)voidSetBufferSize(size_t size){buffer_size_size;}voidSetTimeout(intsec,intusec0){timeout_sec_sec;timeout_usec_usec;}voidSetReuseAddr(boolreuse){reuse_addr_reuse;}private:// 創(chuàng)建套接字boolCreateSocket();// 綁定地址boolBindAddress();// 設(shè)置套接字選項(xiàng)boolSetSocketOptions();// 處理接收到的數(shù)據(jù)virtualvoidProcessData(constchar*data,ssize_t len,conststructsockaddr_inclient_addr);// 發(fā)送響應(yīng)boolSendResponse(constchar*data,ssize_t len,conststructsockaddr_inclient_addr);// 清理資源voidCleanup();};#endif// UDPSERVER_HPP1.2 初始化函數(shù)Init詳解初始化函數(shù)是服務(wù)器啟動(dòng)的第一步它負(fù)責(zé)套接字創(chuàng)建、地址綁定和選項(xiàng)設(shè)置等關(guān)鍵操作。boolUdpServer::Init(){// 1. 創(chuàng)建日志實(shí)例Logger::Instance().Init(udp_server.log,LogLevel::INFO);LOG_INFO(Starting UDP server initialization...);// 2. 創(chuàng)建套接字if(!CreateSocket()){LOG_ERROR(Failed to create socket);returnfalse;}// 3. 設(shè)置套接字選項(xiàng)if(!SetSocketOptions()){LOG_ERROR(Failed to set socket options);close(sockfd_);returnfalse;}// 4. 綁定地址if(!BindAddress()){LOG_ERROR(Failed to bind address);close(sockfd_);returnfalse;}// 5. 初始化客戶端地址結(jié)構(gòu)memset(client_addr_,0,sizeof(client_addr_));client_addr_len_sizeof(client_addr_);LOG_INFO(UDP server initialized successfully on port %d,port_);LOG_INFO(Buffer size: %zu bytes,buffer_size_);LOG_INFO(Timeout: %d seconds %d microseconds,timeout_sec_,timeout_usec_);returntrue;}boolUdpServer::CreateSocket(){// 使用AF_INET表示IPv4SOCK_DGRAM表示UDP協(xié)議sockfd_socket(AF_INET,SOCK_DGRAM,0);if(sockfd_0){LOG_ERROR(Socket creation failed: %s,strerror(errno));returnfalse;}LOG_DEBUG(Socket created successfully, fd: %d,sockfd_);returntrue;}boolUdpServer::SetSocketOptions(){intoptval1;// 設(shè)置地址重用選項(xiàng)避免Address already in use錯(cuò)誤if(reuse_addr_){if(setsockopt(sockfd_,SOL_SOCKET,SO_REUSEADDR,optval,sizeof(optval))0){LOG_WARN(Failed to set SO_REUSEADDR: %s,strerror(errno));// 注意這不是致命錯(cuò)誤可以繼續(xù)運(yùn)行}else{LOG_DEBUG(SO_REUSEADDR set successfully);}}// 設(shè)置接收超時(shí)if(timeout_sec_0||timeout_usec_0){structtimevaltv;tv.tv_sectimeout_sec_;tv.tv_usectimeout_usec_;if(setsockopt(sockfd_,SOL_SOCKET,SO_RCVTIMEO,tv,sizeof(tv))0){LOG_WARN(Failed to set receive timeout: %s,strerror(errno));}else{LOG_DEBUG(Receive timeout set to %ld.%06ld seconds,tv.tv_sec,tv.tv_usec);}}// 設(shè)置發(fā)送緩沖區(qū)大小intsend_buf_size1024*1024;// 1MBif(setsockopt(sockfd_,SOL_SOCKET,SO_SNDBUF,send_buf_size,sizeof(send_buf_size))0){LOG_WARN(Failed to set send buffer size: %s,strerror(errno));}// 設(shè)置接收緩沖區(qū)大小intrecv_buf_size1024*1024;// 1MBif(setsockopt(sockfd_,SOL_SOCKET,SO_RCVBUF,recv_buf_size,sizeof(recv_buf_size))0){LOG_WARN(Failed to set receive buffer size: %s,strerror(errno));}returntrue;}boolUdpServer::BindAddress(){// 初始化服務(wù)器地址結(jié)構(gòu)memset(server_addr_,0,sizeof(server_addr_));// 設(shè)置地址族為IPv4server_addr_.sin_familyAF_INET;// 設(shè)置端口使用htons進(jìn)行字節(jié)序轉(zhuǎn)換server_addr_.sin_porthtons(port_);// 設(shè)置IP地址為INADDR_ANY表示監(jiān)聽所有網(wǎng)絡(luò)接口server_addr_.sin_addr.s_addrhtonl(INADDR_ANY);// 綁定套接字到指定地址和端口if(bind(sockfd_,(structsockaddr*)server_addr_,sizeof(server_addr_))0){LOG_ERROR(Bind failed on port %d: %s,port_,strerror(errno));returnfalse;}// 獲取實(shí)際綁定的地址信息structsockaddr_inactual_addr;socklen_t actual_lensizeof(actual_addr);if(getsockname(sockfd_,(structsockaddr*)actual_addr,actual_len)0){charip_str[INET_ADDRSTRLEN];inet_ntop(AF_INET,actual_addr.sin_addr,ip_str,sizeof(ip_str));LOG_INFO(Server bound to %s:%d,ip_str,ntohs(actual_addr.sin_port));}returntrue;}1.3 關(guān)鍵系統(tǒng)調(diào)用詳解1.3.1 inet_addr函數(shù)inet_addr函數(shù)用于將點(diǎn)分十進(jìn)制表示的IPv4地址轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)序的32位整數(shù)。雖然本文代碼中使用的是inet_pton更安全的版本但理解inet_addr仍然很重要。// inet_addr的使用示例constchar*ip_str192.168.1.100;in_addr_t addrinet_addr(ip_str);if(addrINADDR_NONE){LOG_ERROR(Invalid IP address: %s,ip_str);}else{LOG_DEBUG(IP %s converted to network byte order: 0x%08x,ip_str,addr);// 轉(zhuǎn)換回點(diǎn)分十進(jìn)制格式structin_addraddr_struct;addr_struct.s_addraddr;char*ip_str_backinet_ntoa(addr_struct);LOG_DEBUG(Converted back to string: %s,ip_str_back);}// 現(xiàn)代推薦使用inet_pton更安全支持IPv6structsockaddr_inaddr;if(inet_pton(AF_INET,ip_str,addr.sin_addr)0){LOG_ERROR(Invalid IP address format: %s,ip_str);}1.3.2 bzero和memset函數(shù)bzero是BSD系統(tǒng)中用于將內(nèi)存區(qū)域清零的函數(shù)而memset是標(biāo)準(zhǔn)C庫(kù)函數(shù)功能更通用。// bzero的使用傳統(tǒng)方式structsockaddr_inaddr;bzero(addr,sizeof(addr));// 將整個(gè)結(jié)構(gòu)體清零// memset的等效用法memset(addr,0,sizeof(addr));// 更標(biāo)準(zhǔn)的做法// memset的更多用途charbuffer[1024];// 全部設(shè)置為0memset(buffer,0,sizeof(buffer));// 全部設(shè)置為特定值memset(buffer,A,sizeof(buffer));// 部分設(shè)置memset(buffer,0,100);// 只清空前100字節(jié)// 性能比較對(duì)于大內(nèi)存塊memset通常經(jīng)過優(yōu)化性能更好1.4 服務(wù)器運(yùn)行函數(shù)RunRun函數(shù)是服務(wù)器的核心負(fù)責(zé)循環(huán)接收客戶端請(qǐng)求并處理。voidUdpServer::Run(){if(sockfd_0){LOG_ERROR(Cannot run server: socket not initialized);return;}is_running_true;LOG_INFO(UDP server started, waiting for connections...);// 分配接收緩沖區(qū)std::vectorcharbuffer(buffer_size_);// 主循環(huán)while(is_running_){// 重置客戶端地址信息memset(client_addr_,0,sizeof(client_addr_));client_addr_len_sizeof(client_addr_);// 接收數(shù)據(jù)ssize_t recv_lenrecvfrom(sockfd_,buffer.data(),buffer.size()-1,0,(structsockaddr*)client_addr_,client_addr_len_);if(recv_len0){// 處理接收錯(cuò)誤if(errnoEAGAIN||errnoEWOULDBLOCK){// 超時(shí)繼續(xù)循環(huán)continue;}elseif(errnoEINTR){// 被信號(hào)中斷LOG_DEBUG(recvfrom interrupted by signal);continue;}else{LOG_ERROR(recvfrom failed: %s,strerror(errno));break;}}elseif(recv_len0){// UDP中recvfrom返回0表示收到了0字節(jié)的數(shù)據(jù)包LOG_DEBUG(Received empty datagram);continue;}// 確保字符串以null結(jié)尾buffer[recv_len];// 獲取客戶端信息charclient_ip[INET_ADDRSTRLEN];inet_ntop(AF_INET,client_addr_.sin_addr,client_ip,sizeof(client_ip));uint16_tclient_portntohs(client_addr_.sin_port);LOG_DEBUG(Received %zd bytes from %s:%d,recv_len,client_ip,client_port);LOG_DEBUG(Data: %s,buffer.data());// 處理數(shù)據(jù)ProcessData(buffer.data(),recv_len,client_addr_);}LOG_INFO(UDP server stopped);Cleanup();}voidUdpServer::ProcessData(constchar*data,ssize_t len,conststructsockaddr_inclient_addr){// 默認(rèn)實(shí)現(xiàn)原樣返回?cái)?shù)據(jù)echo服務(wù)器LOG_DEBUG(Processing %zd bytes of data,len);// 構(gòu)造響應(yīng)std::string responseServer received: ;response.append(data,len);// 發(fā)送響應(yīng)if(!SendResponse(response.c_str(),response.length(),client_addr)){LOG_ERROR(Failed to send response to client);}}boolUdpServer::SendResponse(constchar*data,ssize_t len,conststructsockaddr_inclient_addr){if(len0){LOG_WARN(Attempting to send empty data);returntrue;// 空數(shù)據(jù)發(fā)送成功}// 發(fā)送數(shù)據(jù)ssize_t sent_lensendto(sockfd_,data,len,0,(conststructsockaddr*)client_addr,sizeof(client_addr));if(sent_len0){LOG_ERROR(sendto failed: %s,strerror(errno));returnfalse;}if(sent_len!len){LOG_WARN(Partial send: %zd of %zd bytes sent,sent_len,len);}// 獲取客戶端信息用于日志charclient_ip[INET_ADDRSTRLEN];inet_ntop(AF_INET,client_addr.sin_addr,client_ip,sizeof(client_ip));uint16_tclient_portntohs(client_addr.sin_port);LOG_DEBUG(Sent %zd bytes to %s:%d,sent_len,client_ip,client_port);returntrue;}1.5 recvfrom和sendto函數(shù)深度解析1.5.1 recvfrom函數(shù)recvfrom是UDP接收數(shù)據(jù)的核心函數(shù)它不僅可以接收數(shù)據(jù)還能獲取發(fā)送者的地址信息。/** * recvfrom函數(shù)原型 * ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, * struct sockaddr *src_addr, socklen_t *addrlen); * * 參數(shù)說(shuō)明 * - sockfd: 套接字描述符 * - buf: 接收緩沖區(qū) * - len: 緩沖區(qū)大小 * - flags: 標(biāo)志位常用值 * * 0: 默認(rèn)行為 * * MSG_WAITALL: 等待所有數(shù)據(jù)對(duì)UDP通常無(wú)效 * * MSG_DONTWAIT: 非阻塞模式 * * MSG_PEEK: 查看數(shù)據(jù)但不從緩沖區(qū)移除 * - src_addr: 發(fā)送方地址輸出參數(shù) * - addrlen: 地址長(zhǎng)度輸入輸出參數(shù) * * 返回值 * - 成功接收到的字節(jié)數(shù) * - 失敗-1設(shè)置errno * - 連接關(guān)閉TCP或空數(shù)據(jù)包UDP0 */// recvfrom的完整示例voidReceiveExample(intsockfd){structsockaddr_inclient_addr;socklen_t addr_lensizeof(client_addr);charbuffer[4096];// 設(shè)置接收超時(shí)structtimevaltv;tv.tv_sec5;tv.tv_usec0;setsockopt(sockfd,SOL_SOCKET,SO_RCVTIMEO,tv,sizeof(tv));// 接收數(shù)據(jù)ssize_t recv_lenrecvfrom(sockfd,buffer,sizeof(buffer)-1,MSG_DONTWAIT,// 非阻塞模式(structsockaddr*)client_addr,addr_len);if(recv_len0){buffer[recv_len];// 獲取客戶端信息charip_str[INET_ADDRSTRLEN];inet_ntop(AF_INET,client_addr.sin_addr,ip_str,sizeof(ip_str));uint16_tportntohs(client_addr.sin_port);LOG_INFO(Received from %s:%d: %s,ip_str,port,buffer);// 處理不同的消息類型ProcessMessage(buffer,recv_len,client_addr);}elseif(recv_len0){LOG_DEBUG(Received empty datagram);}else{// 錯(cuò)誤處理if(errnoEAGAIN||errnoEWOULDBLOCK){LOG_DEBUG(No data available (non-blocking));}elseif(errnoEINTR){LOG_DEBUG(Interrupted by signal);}else{LOG_ERROR(Receive error: %s,strerror(errno));}}}// 處理不同類型的消息voidProcessMessage(constchar*data,ssize_t len,conststructsockaddr_inclient_addr){// 簡(jiǎn)單的協(xié)議處理示例if(len4strncmp(data,PING,4)0){LOG_DEBUG(Received PING request);SendResponse(PONG,4,client_addr);}elseif(len4strncmp(data,TIME,4)0){time_t nowtime(nullptr);std::string time_strctime(now);SendResponse(time_str.c_str(),time_str.length(),client_addr);}elseif(len7strncmp(data,ECHO ,5)0){// 回顯消息內(nèi)容SendResponse(data5,len-5,client_addr);}else{std::string responseUnknown command: ;response.append(data,len);SendResponse(response.c_str(),response.length(),client_addr);}}1.5.2 sendto函數(shù)sendto是UDP發(fā)送數(shù)據(jù)的核心函數(shù)用于向指定地址發(fā)送數(shù)據(jù)報(bào)。/** * sendto函數(shù)原型 * ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, * const struct sockaddr *dest_addr, socklen_t addrlen); * * 參數(shù)說(shuō)明 * - sockfd: 套接字描述符 * - buf: 發(fā)送緩沖區(qū) * - len: 要發(fā)送的數(shù)據(jù)長(zhǎng)度 * - flags: 標(biāo)志位常用值 * * 0: 默認(rèn)行為 * * MSG_DONTWAIT: 非阻塞模式 * * MSG_CONFIRM: 確認(rèn)路由有效Linux特有 * * MSG_MORE: 還有更多數(shù)據(jù)要發(fā)送 * - dest_addr: 目標(biāo)地址 * - addrlen: 地址長(zhǎng)度 * * 返回值 * - 成功發(fā)送的字節(jié)數(shù)可能小于len * - 失敗-1設(shè)置errno */// sendto的完整示例boolSendData(intsockfd,constvoid*data,size_t len,conststructsockaddr_indest_addr){if(len0){LOG_WARN(Attempting to send zero-length data);returntrue;}// 檢查數(shù)據(jù)包大小UDP最大約64KB實(shí)際建議小于1500字節(jié)避免分片if(len65507){// 65535 - 20(IP頭) - 8(UDP頭)LOG_ERROR(Datagram too large: %zu bytes (max: 65507),len);returnfalse;}if(len1400){LOG_WARN(Large datagram: %zu bytes (may be fragmented),len);}// 分塊發(fā)送大數(shù)據(jù)如果需要constsize_t MAX_CHUNK1400;// 避免IP分片的推薦大小size_t total_sent0;while(total_sentlen){size_t chunk_sizestd::min(MAX_CHUNK,len-total_sent);constchar*chunk_startstatic_castconstchar*(data)total_sent;ssize_t sentsendto(sockfd,chunk_start,chunk_size,0,(conststructsockaddr*)dest_addr,sizeof(dest_addr));if(sent0){LOG_ERROR(Failed to send chunk: %s (sent %zu/%zu bytes),strerror(errno),total_sent,len);returnfalse;}total_sentsent;// 添加小延遲避免擁塞if(chunk_sizeMAX_CHUNKtotal_sentlen){usleep(1000);// 1ms延遲}}LOG_DEBUG(Successfully sent %zu bytes to %s:%d,total_sent,inet_ntoa(dest_addr.sin_addr),ntohs(dest_addr.sin_port));returntrue;}// 發(fā)送不同類型的消息voidSendVariousMessages(intsockfd,conststructsockaddr_indest_addr){// 1. 發(fā)送字符串constchar*textHello, UDP Server!;SendData(sockfd,text,strlen(text),dest_addr);// 2. 發(fā)送二進(jìn)制數(shù)據(jù)structBinaryData{uint32_tmagic;uint16_tversion;uint8_ttype;uint8_tdata[256];}binary_msg;binary_msg.magichtonl(0xDEADBEEF);binary_msg.versionhtons(1);binary_msg.type0x42;memset(binary_msg.data,0xAA,sizeof(binary_msg.data));SendData(sockfd,binary_msg,sizeof(binary_msg),dest_addr);// 3. 發(fā)送結(jié)構(gòu)化數(shù)據(jù)JSON格式std::string json_msgR({ command: update, timestamp: )std::to_string(time(nullptr))R(, data: {temperature: 23.5, humidity: 65.2} });SendData(sockfd,json_msg.c_str(),json_msg.length(),dest_addr);// 4. 發(fā)送帶序列號(hào)的消息for(inti0;i10;i){std::string seq_msgMessage #std::to_string(i);SendData(sockfd,seq_msg.c_str(),seq_msg.length(),dest_addr);// 添加延遲usleep(100000);// 100ms}}1.6 高級(jí)功能多線程處理和連接管理對(duì)于高性能UDP服務(wù)器我們需要考慮多線程處理和客戶端連接管理。// 擴(kuò)展UdpServer類添加多線程支持classAdvancedUdpServer:publicUdpServer{private:std::vectorstd::threadworker_threads_;std::atomicintthread_count_;intmax_workers_;// 線程池和工作隊(duì)列std::queuestd::pairstd::vectorchar,sockaddr_intask_queue_;std::mutex queue_mutex_;std::condition_variable queue_cv_;public:AdvancedUdpServer(intport8080,intmax_workers4):UdpServer(port),max_workers_(max_workers),thread_count_(0){}~AdvancedUdpServer(){Stop();}boolInit()override{if(!UdpServer::Init()){returnfalse;}// 創(chuàng)建工作線程for(inti0;imax_workers_;i){worker_threads_.emplace_back(AdvancedUdpServer::WorkerThread,this,i);}LOG_INFO(Started %d worker threads,max_workers_);returntrue;}voidRun()override{if(sockfd_0){LOG_ERROR(Socket not initialized);return;}is_running_true;LOG_INFO(Advanced UDP server started on port %d,port_);std::vectorcharbuffer(buffer_size_);while(is_running_){structsockaddr_inclient_addr;socklen_t addr_lensizeof(client_addr);// 接收數(shù)據(jù)ssize_t recv_lenrecvfrom(sockfd_,buffer.data(),buffer.size()-1,0,(structsockaddr*)client_addr,addr_len);if(recv_len0){if(errnoEAGAIN||errnoEWOULDBLOCK){continue;}elseif(errnoEINTR){continue;}else{LOG_ERROR(Receive error: %s,strerror(errno));break;}}if(recv_len0){buffer[recv_len];// 將任務(wù)加入隊(duì)列{std::lock_guardstd::mutexlock(queue_mutex_);task_queue_.emplace(std::vectorchar(buffer.begin(),buffer.begin()recv_len),client_addr);}// 通知工作線程queue_cv_.notify_one();// 獲取統(tǒng)計(jì)信息if(task_queue_.size()10){LOG_WARN(Task queue size: %zu,task_queue_.size());}}}// 通知所有工作線程退出queue_cv_.notify_all();// 等待所有線程結(jié)束for(autothread:worker_threads_){if(thread.joinable()){thread.join();}}LOG_INFO(Advanced UDP server stopped);Cleanup();}private:voidWorkerThread(intthread_id){thread_count_;LOG_DEBUG(Worker thread %d started,thread_id);while(is_running_){std::pairstd::vectorchar,sockaddr_intask;{std::unique_lockstd::mutexlock(queue_mutex_);queue_cv_.wait(lock,[this](){return!task_queue_.empty()||!is_running_;});if(!is_running_task_queue_.empty()){break;}if(!task_queue_.empty()){taskstd::move(task_queue_.front());task_queue_.pop();}else{continue;}}// 處理任務(wù)ProcessTask(task.first,task.second,thread_id);}thread_count_--;LOG_DEBUG(Worker thread %d stopped,thread_id);}voidProcessTask(conststd::vectorchardata,constsockaddr_inclient_addr,intthread_id){// 獲取客戶端信息charclient_ip[INET_ADDRSTRLEN];inet_ntop(AF_INET,client_addr.sin_addr,client_ip,sizeof(client_ip));uint16_tclient_portntohs(client_addr.sin_port);LOG_DEBUG(Thread %d processing %zu bytes from %s:%d,thread_id,data.size(),client_ip,client_port);// 模擬處理時(shí)間std::this_thread::sleep_for(std::chrono::milliseconds(10));// 處理數(shù)據(jù)std::string responseThread std::to_string(thread_id) processed: std::string(data.begin(),data.end());SendResponse(response.c_str(),response.length(),client_addr);}};// 連接管理類classConnectionManager{private:structClientInfo{sockaddr_in address;time_t last_activity;uint64_tpacket_count;uint64_ttotal_bytes;ClientInfo(constsockaddr_inaddr):address(addr),last_activity(time(nullptr)),packet_count(0),total_bytes(0){}};std::unordered_mapstd::string,ClientInfoclients_;std::mutex clients_mutex_;time_t cleanup_interval_;public:ConnectionManager(time_t cleanup_interval300)// 5分鐘:cleanup_interval_(cleanup_interval){}// 更新客戶端活動(dòng)voidUpdateClient(constsockaddr_inaddr,size_t bytes){std::string keyGetClientKey(addr);std::lock_guardstd::mutexlock(clients_mutex_);autoitclients_.find(key);if(itclients_.end()){// 新客戶端clients_.emplace(key,ClientInfo(addr));itclients_.find(key);charip_str[INET_ADDRSTRLEN];inet_ntop(AF_INET,addr.sin_addr,ip_str,sizeof(ip_str));LOG_INFO(New client connected: %s:%d,ip_str,ntohs(addr.sin_port));}// 更新統(tǒng)計(jì)信息it-second.last_activitytime(nullptr);it-second.packet_count;it-second.total_bytesbytes;}// 清理不活躍的連接voidCleanupInactiveClients(){time_t nowtime(nullptr);std::vectorstd::stringto_remove;{std::lock_guardstd::mutexlock(clients_mutex_);for(constautopair:clients_){if(now-pair.second.last_activitycleanup_interval_){to_remove.push_back(pair.first);}}for(constautokey:to_remove){constautoclientclients_[key];charip_str[INET_ADDRSTRLEN];inet_ntop(AF_INET,client.address.sin_addr,ip_str,sizeof(ip_str));LOG_INFO(Client %s:%d disconnected (inactive). Packets: %lu, Bytes: %lu,ip_str,ntohs(client.address.sin_port),client.packet_count,client.total_bytes);clients_.erase(key);}}if(!to_remove.empty()){LOG_INFO(Cleaned up %zu inactive clients,to_remove.size());}}// 獲取客戶端統(tǒng)計(jì)信息std::stringGetStats()const{std::lock_guardstd::mutexlock(clients_mutex_);std::stringstream ss;ssActive clients: clients_.size() ;for(constautopair:clients_){charip_str[INET_ADDRSTRLEN];inet_ntop(AF_INET,pair.second.address.sin_addr,ip_str,sizeof(ip_str));ssip_str:ntohs(pair.second.address.sin_port) - Packets: pair.second.packet_count, Bytes: pair.second.total_bytes, Last activity: (time(nullptr)-pair.second.last_activity) seconds ago ;}returnss.str();}private:std::stringGetClientKey(constsockaddr_inaddr)const{std::stringstream ss;ssinet_ntoa(addr.sin_addr):ntohs(addr.sin_port);returnss.str();}};二、Main.cc實(shí)現(xiàn)主程序負(fù)責(zé)初始化服務(wù)器并處理命令行參數(shù)。#includeiostream#includecsignal#includecstdlib#includememory#includeUdpServer.hpp#includeAdvancedUdpServer.hpp// 全局服務(wù)器指針用于信號(hào)處理std::unique_ptrUdpServerg_server;// 信號(hào)處理函數(shù)voidSignalHandler(intsignal){std::cout Received signal signal, shutting down...std::endl;if(g_server){g_server-Stop();}}// 顯示使用幫助voidShowUsage(constchar*program_name){std::coutUDP Server v1.0 ;std::coutUsage: program_name [options] ;std::coutOptions: ;std::cout -p, --port PORT Server port (default: 8080) ;std::cout -b, --buffer SIZE Buffer size in bytes (default: 4096) ;std::cout -t, --timeout SEC Receive timeout in seconds (default: 5) ;std::cout -w, --workers NUM Number of worker threads (default: 1) ;std::cout -a, --advanced Use advanced server with thread pool ;std::cout -h, --help Show this help message ;std::cout Examples: ;std::cout program_name -p 9000 -b 8192 ;std::cout program_name --port 8080 --workers 4 --advanced ;}// 解析命令行參數(shù)structServerConfig{intport8080;size_t buffer_size4096;inttimeout_sec5;inttimeout_usec0;intworkers1;booladvancedfalse;boolreuse_addrtrue;};ServerConfigParseArguments(intargc,char*argv[]){ServerConfig config;for(inti1;iargc;i){std::string argargv[i];if(arg-p||arg--port){if(i1argc){config.portstd::atoi(argv[i]);if(config.port0||config.port65535){std::cerrError: Port must be between 1 and 65535std::endl;exit(1);}}}elseif(arg-b||arg--buffer){if(i1argc){config.buffer_sizestd::atoi(argv[i]);if(config.buffer_size1024||config.buffer_size65536){std::cerrError: Buffer size must be between 1024 and 65536std::endl;exit(1);}}}elseif(arg-t||arg--timeout){if(i1argc){config.timeout_secstd::atoi(argv[i]);if(config.timeout_sec0){std::cerrError: Timeout must be non-negativestd::endl;exit(1);}}}elseif(arg-w||arg--workers){if(i1argc){config.workersstd::atoi(argv[i]);if(config.workers1||config.workers32){std::cerrError: Number of workers must be between 1 and 32std::endl;exit(1);}}}elseif(arg-a||arg--advanced){config.advancedtrue;}elseif(arg-h||arg--help){ShowUsage(argv[0]);exit(0);}elseif(arg--no-reuse){config.reuse_addrfalse;}else{std::cerrError: Unknown option argstd::endl;ShowUsage(argv[0]);exit(1);}}returnconfig;}intmain(intargc,char*argv[]){// 解析命令行參數(shù)ServerConfig configParseArguments(argc,argv);// 注冊(cè)信號(hào)處理signal(SIGINT,SignalHandler);signal(SIGTERM,SignalHandler);try{std::cout UDP Server Starting ;std::coutPort: config.port ;std::coutBuffer size: config.buffer_size bytes ;std::coutTimeout: config.timeout_sec seconds ;std::coutWorkers: config.workers ;std::coutMode: (config.advanced?Advanced:Basic) ;std::cout ;// 創(chuàng)建服務(wù)器實(shí)例if(config.advanced){g_serverstd::make_uniqueAdvancedUdpServer(config.port,config.workers);}else{g_serverstd::make_uniqueUdpServer(config.port);}// 配置服務(wù)器g_server-SetBufferSize(config.buffer_size);g_server-SetTimeout(config.timeout_sec,config.timeout_usec);g_server-SetReuseAddr(config.reuse_addr);// 初始化服務(wù)器if(!g_server-Init()){std::cerrFailed to initialize serverstd::endl;return1;}std::coutServer initialized successfully ;std::coutPress CtrlC to stop the server ;// 運(yùn)行服務(wù)器g_server-Run();}catch(conststd::exceptione){std::cerrException: e.what()std::endl;return1;}catch(...){std::cerrUnknown exception occurredstd::endl;return1;}std::cout Server stopped gracefullystd::endl;return0;}// 性能測(cè)試函數(shù)voidRunPerformanceTest(intport){std::cout Performance Test ;// 創(chuàng)建測(cè)試服務(wù)器autotest_serverstd::make_uniqueAdvancedUdpServer(port,4);test_server-SetBufferSize(65536);test_server-SetTimeout(1,0);if(!test_server-Init()){std::cerrFailed to initialize test serverstd::endl;return;}// 在后臺(tái)運(yùn)行服務(wù)器std::threadserver_thread([test_server](){test_server-Run();});// 給服務(wù)器時(shí)間啟動(dòng)std::this_thread::sleep_for(std::chrono::seconds(1));// 創(chuàng)建測(cè)試客戶端intclient_socksocket(AF_INET,SOCK_DGRAM,0);if(client_sock0){std::cerrFailed to create test client socketstd::endl;return;}structsockaddr_inserver_addr;memset(server_addr,0,sizeof(server_addr));server_addr.sin_familyAF_INET;server_addr.sin_porthtons(port);server_addr.sin_addr.s_addrhtonl(INADDR_LOOPBACK);// 測(cè)試參數(shù)constintNUM_PACKETS10000;constintPACKET_SIZE1024;std::vectorchartest_data(PACKET_SIZE,X);autostart_timestd::chrono::high_resolution_clock::now();// 發(fā)送測(cè)試數(shù)據(jù)包for(inti0;iNUM_PACKETS;i){// 在數(shù)據(jù)中包含序列號(hào)memcpy(test_data.data(),i,sizeof(i));ssize_t sentsendto(client_sock,test_data.data(),PACKET_SIZE,0,(structsockaddr*)server_addr,sizeof(server_addr));if(sent!PACKET_SIZE){std::cerrFailed to send packet istd::endl;break;}// 每1000個(gè)包打印進(jìn)度if((i1)%10000){std::coutSent (i1) packets...std::endl;}// 小延遲避免擁塞usleep(10);}autoend_timestd::chrono::high_resolution_clock::now();autodurationstd::chrono::duration_caststd::chrono::milliseconds(end_time-start_time);close(client_sock);// 停止服務(wù)器test_server-Stop();if(server_thread.joinable()){server_thread.join();}// 輸出結(jié)果std::cout Performance Test Results: ;std::coutPackets sent: NUM_PACKETS ;std::coutPacket size: PACKET_SIZE bytes ;std::coutTotal data: (NUM_PACKETS*PACKET_SIZE/1024.0/1024.0) MB ;std::coutTotal time: duration.count() ms ;std::coutThroughput: (NUM_PACKETS*PACKET_SIZE*8.0/duration.count()/1000.0) Mbps ;std::coutPackets per second: (NUM_PACKETS*1000.0/duration.count()) ;}三、UDP客戶端UdpClient.cc3.1 基本框架設(shè)計(jì)UDP客戶端的設(shè)計(jì)需要簡(jiǎn)潔高效支持多種操作模式。#ifndefUDPCLIENT_H#defineUDPCLIENT_H#includeiostream#includestring#includecstring#includecstdlib#includeunistd.h#includearpa/inet.h#includesys/socket.h#includesys/types.h#includenetinet/in.h#includevector#includechrono#includethread#includeatomic#includememory#includeiomanipclassUdpClient{private:intsockfd_;// 套接字描述符structsockaddr_inserver_addr_;// 服務(wù)器地址std::string server_ip_;// 服務(wù)器IP地址intserver_port_;// 服務(wù)器端口// 客戶端狀態(tài)std::atomicboolis_connected_;std::atomicboolis_running_;// 統(tǒng)計(jì)信息uint64_tpackets_sent_;uint64_tpackets_received_;uint64_tbytes_sent_;uint64_tbytes_received_;public:// 構(gòu)造函數(shù)UdpClient(conststd::stringip127.0.0.1,intport8080);// 析構(gòu)函數(shù)~UdpClient();// 初始化客戶端boolInit();// 連接服務(wù)器boolConnect();// 發(fā)送數(shù)據(jù)boolSend(conststd::stringdata);boolSend(constvoid*data,size_t len);// 接收數(shù)據(jù)阻塞boolReceive(std::stringdata,inttimeout_ms5000);// 發(fā)送并等待響應(yīng)boolSendAndReceive(conststd::stringsend_data,std::stringrecv_data,inttimeout_ms5000);// 運(yùn)行交互模式voidRunInteractive();// 運(yùn)行性能測(cè)試模式voidRunPerformanceTest(intnum_packets1000,intpacket_size1024);// 獲取統(tǒng)計(jì)信息voidGetStats(uint64_tsent_packets,uint64_treceived_packets,uint64_tsent_bytes,uint64_treceived_bytes)const;// 重置統(tǒng)計(jì)信息voidResetStats();// 斷開連接voidDisconnect();private:// 創(chuàng)建套接字boolCreateSocket();// 設(shè)置套接字選項(xiàng)boolSetSocketOptions();// 打印狀態(tài)voidPrintStatus()const;// 顯示幫助信息voidShowHelp()const;};#endif// UDPCLIENT_H3.2 創(chuàng)建套接字和連接#includeUdpClient.hUdpClient::UdpClient(conststd::stringip,intport):server_ip_(ip),server_port_(port),sockfd_(-1),is_connected_(false),is_running_(false),packets_sent_(0),packets_received_(0),bytes_sent_(0),bytes_received_(0){// 初始化服務(wù)器地址結(jié)構(gòu)memset(server_addr_,0,sizeof(server_addr_));server_addr_.sin_familyAF_INET;server_addr_.sin_porthtons(server_port_);// 轉(zhuǎn)換IP地址if(inet_pton(AF_INET,server_ip_.c_str(),server_addr_.sin_addr)0){std::cerrInvalid IP address: server_ip_std::endl;}}UdpClient::~UdpClient(){Disconnect();}boolUdpClient::Init(){// 創(chuàng)建套接字if(!CreateSocket()){std::cerrFailed to create socketstd::endl;returnfalse;}// 設(shè)置套接字選項(xiàng)if(!SetSocketOptions()){std::cerrFailed to set socket optionsstd::endl;close(sockfd_);returnfalse;}std::coutUDP client initializedstd::endl;std::coutServer: server_ip_:server_port_std::endl;returntrue;}boolUdpClient::CreateSocket(){// 創(chuàng)建UDP套接字sockfd_socket(AF_INET,SOCK_DGRAM,0);if(sockfd_0){std::cerrSocket creation failed: strerror(errno)std::endl;returnfalse;}std::coutSocket created successfully (fd: sockfd_)std::endl;returntrue;}boolUdpClient::SetSocketOptions(){intoptval1;// 設(shè)置接收超時(shí)structtimevaltv;tv.tv_sec5;tv.tv_usec0;if(setsockopt(sockfd_,SOL_SOCKET,SO_RCVTIMEO,tv,sizeof(tv))0){std::cerrFailed to set receive timeout: strerror(errno)std::endl;returnfalse;}// 啟用廣播如果需要optval1;if(setsockopt(sockfd_,SOL_SOCKET,SO_BROADCAST,optval,sizeof(optval))0){std::cerrWarning: Failed to enable broadcast: strerror(errno)std::endl;}// 設(shè)置緩沖區(qū)大小intbuf_size1024*1024;// 1MBif(setsockopt(sockfd_,SOL_SOCKET,SO_RCVBUF,buf_size,sizeof(buf_size))0){std::cerrWarning: Failed to set receive buffer: strerror(errno)std::endl;}if(setsockopt(sockfd_,SOL_SOCKET,SO_SNDBUF,buf_size,sizeof(buf_size))0){std::cerrWarning: Failed to set send buffer: strerror(errno)std::endl;}returntrue;}boolUdpClient::Connect(){if(sockfd_0){std::cerrSocket not initializedstd::endl;returnfalse;}// UDP是無(wú)連接的這里只是測(cè)試與服務(wù)器的連通性std::string test_msgCONNECT_TEST;std::string response;if(SendAndReceive(test_msg,response,3000)){std::coutSuccessfully connected to serverstd::endl;std::coutServer response: responsestd::endl;is_connected_true;returntrue;}else{std::cerrFailed to connect to serverstd::endl;returnfalse;}}3.3 發(fā)送和接收數(shù)據(jù)boolUdpClient::Send(conststd::stringdata){returnSend(data.c_str(),data.length());}boolUdpClient::Send(constvoid*data,size_t len){if(sockfd_0){std::cerrSocket not initializedstd::endl;returnfalse;}if(len0){std::cerrAttempting to send empty datastd::endl;returnfalse;}// 檢查數(shù)據(jù)包大小if(len65507){std::cerrData too large: len bytes (max: 65507)std::endl;returnfalse;}// 發(fā)送數(shù)據(jù)ssize_t sentsendto(sockfd_,data,len,0,(structsockaddr*)server_addr_,sizeof(server_addr_));if(sent0){std::cerrSend failed: strerror(errno)std::endl;returnfalse;}if(static_castsize_t(sent)!len){std::cerrPartial send: sent of len bytesstd::endl;}// 更新統(tǒng)計(jì)信息packets_sent_;bytes_sent_sent;std::coutSent sent bytes to server_ip_:server_port_std::endl;returntrue;}boolUdpClient::Receive(std::stringdata,inttimeout_ms){if(sockfd_0){std::cerrSocket not initializedstd::endl;returnfalse;}// 設(shè)置接收超時(shí)if(timeout_ms0){structtimevaltv;tv.tv_sectimeout_ms/1000;tv.tv_usec(timeout_ms%1000)*1000;setsockopt(sockfd_,SOL_SOCKET,SO_RCVTIMEO,tv,sizeof(tv));}// 接收緩沖區(qū)charbuffer[65536];structsockaddr_infrom_addr;socklen_t addr_lensizeof(from_addr);// 接收數(shù)據(jù)ssize_t recv_lenrecvfrom(sockfd_,buffer,sizeof(buffer)-1,0,(structsockaddr*)from_addr,addr_len);if(recv_len0){if(errnoEAGAIN||errnoEWOULDBLOCK){std::coutReceive timeoutstd::endl;}else{std::cerrReceive failed: strerror(errno)std::endl;}returnfalse;}// 確保字符串以null結(jié)尾buffer[recv_len];data.assign(buffer,recv_len);// 獲取發(fā)送者信息charfrom_ip[INET_ADDRSTRLEN];inet_ntop(AF_INET,from_addr.sin_addr,from_ip,sizeof(from_ip));uint16_tfrom_portntohs(from_addr.sin_port);// 更新統(tǒng)計(jì)信息packets_received_;bytes_received_recv_len;std::coutReceived recv_len bytes from from_ip:from_portstd::endl;returntrue;}boolUdpClient::SendAndReceive(conststd::stringsend_data,std::stringrecv_data,inttimeout_ms){// 發(fā)送數(shù)據(jù)if(!Send(send_data)){returnfalse;}// 接收響應(yīng)if(!Receive(recv_data,timeout_ms)){returnfalse;}returntrue;}3.4 交互模式和性能測(cè)試voidUdpClient::RunInteractive(){if(!is_connected_){if(!Connect()){std::cerrCannot start interactive mode: not connectedstd::endl;return;}}is_running_true;std::cout UDP Client Interactive Mode ;std::coutType help for commands, quit to exit ;std::string input;while(is_running_){std::coutudp ;std::getline(std::cin,input);if(input.empty()){continue;}// 處理命令if(inputquit||inputexit){std::coutExiting...std::endl;break;}elseif(inputhelp){ShowHelp();}elseif(inputstatus){PrintStatus();}elseif(inputstats){std::cout Statistics ;std::coutPackets sent: packets_sent_ ;std::coutPackets received: packets_received_ ;std::coutBytes sent: bytes_sent_ ;std::coutBytes received: bytes_received_ ;if(packets_sent_0){std::coutAverage sent size: (bytes_sent_/packets_sent_) bytes ;}if(packets_received_0){std::coutAverage received size: (bytes_received_/packets_received_) bytes ;}}elseif(inputreset){ResetStats();std::coutStatistics resetstd::endl;}elseif(inputping){std::string response;if(SendAndReceive(PING,response)){std::coutServer response: responsestd::endl;}}elseif(inputtime){std::string response;if(SendAndReceive(TIME,response)){std::coutServer time: response;}}elseif(input.compare(0,4,echo)0){if(input.length()5){std::string echo_datainput.substr(5);std::string response;if(SendAndReceive(ECHO echo_data,response)){std::coutEcho: responsestd::endl;}}else{std::coutUsage: echo messagestd::endl;}}elseif(input.compare(0,4,file)0){// 模擬文件傳輸std::string filenameinput.length()5?input.substr(5):test.txt;std::coutSimulating file transfer: filenamestd::endl;// 創(chuàng)建模擬文件內(nèi)容std::string file_content;for(inti0;i100;i){file_contentLine std::to_string(i1): This is test data ;}// 分塊發(fā)送constsize_t CHUNK_SIZE1024;size_t total_sent0;intchunk_num1;for(size_t i0;ifile_content.length();iCHUNK_SIZE){size_t chunk_lenstd::min(CHUNK_SIZE,file_content.length()-i);std::string chunkfile_content.substr(i,chunk_len);// 添加塊頭信息std::string chunk_with_headerFILE_CHUNK std::to_string(chunk_num) chunk;if(Send(chunk_with_header)){total_sentchunk_len;std::coutSent chunk chunk_num (chunk_len bytes)std::endl;chunk_num;// 小延遲usleep(10000);// 10ms}else{std::cerrFailed to send chunk chunk_numstd::endl;break;}}std::coutFile transfer complete: total_sent bytes sentstd::endl;}elseif(inputperftest){RunPerformanceTest();}else{// 默認(rèn)發(fā)送原始消息std::string response;if(SendAndReceive(input,response)){std::coutResponse: responsestd::endl;}}}}voidUdpClient::RunPerformanceTest(intnum_packets,intpacket_size){std::cout Performance Test ;std::coutPackets: num_packets ;std::coutPacket size: packet_size bytes ;std::coutTotal data: (num_packets*packet_size/1024.0/1024.0) MB ;// 準(zhǔn)備測(cè)試數(shù)據(jù)std::vectorchartest_data(packet_size,X);// 記錄開始時(shí)間autostart_timestd::chrono::high_resolution_clock::now();// 發(fā)送測(cè)試數(shù)據(jù)包intsuccessful_sends0;for(inti0;inum_packets;i){// 在數(shù)據(jù)中包含序列號(hào)和時(shí)間戳uint64_tseqi;autotimestampstd::chrono::high_resolution_clock::now();uint64_ttimestamp_nsstd::chrono::duration_caststd::chrono::nanoseconds(timestamp.time_since_epoch()).count();// 將序列號(hào)和時(shí)間戳復(fù)制到數(shù)據(jù)開始處memcpy(test_data.data(),seq,sizeof(seq));memcpy(test_data.data()sizeof(seq),timestamp_ns,sizeof(timestamp_ns));if(Send(test_data.data(),packet_size)){successful_sends;}// 每100個(gè)包打印進(jìn)度if((i1)%1000){std::coutSent (i1) packets...std::endl;}// 控制發(fā)送速率1000 packets/secondusleep(1000);}// 記錄結(jié)束時(shí)間autoend_timestd::chrono::high_resolution_clock::now();autodurationstd::chrono::duration_caststd::chrono::milliseconds(end_time-start_time);// 接收響應(yīng)可選std::cout Waiting for responses...std::endl;intresponses_received0;autoreceive_startstd::chrono::high_resolution_clock::now();// 設(shè)置短超時(shí)接收剩余響應(yīng)structtimevaltv;tv.tv_sec2;tv.tv_usec0;setsockopt(sockfd_,SOL_SOCKET,SO_RCVTIMEO,tv,sizeof(tv));charbuffer[65536];while(true){ssize_t recv_lenrecvfrom(sockfd_,buffer,sizeof(buffer)-1,0,NULL,NULL);if(recv_len0){responses_received;// 解析響應(yīng)中的序列號(hào)if(recv_lensizeof(uint64_t)){uint64_tseq;memcpy(seq,buffer,sizeof(seq));// 可以在這里計(jì)算往返時(shí)間等}}else{break;// 超時(shí)}}autoreceive_endstd::chrono::high_resolution_clock::now();autoreceive_durationstd::chrono::duration_caststd::chrono::milliseconds(receive_end-receive_start);// 輸出結(jié)果std::cout Test Results ;std::coutPackets sent: successful_sends/num_packets ;std::coutResponses received: responses_received ;std::coutSend duration: duration.count() ms ;std::coutReceive duration: receive_duration.count() ms ;if(duration.count()0){doublesend_rate(successful_sends*1000.0)/duration.count();doublethroughput(successful_sends*packet_size*8.0)/(duration.count()*1000.0);// Mbpsstd::coutSend rate: send_rate packets/second ;std::coutThroughput: throughput Mbps ;}if(responses_received0){doubleresponse_rate(responses_received*1000.0)/receive_duration.count();std::coutResponse rate: response_rate packets/second ;}doubleloss_rate0;if(successful_sends0){loss_rate(1.0-(responses_received/(double)successful_sends))*100.0;std::coutPacket loss rate: std::fixedstd::setprecision(2)loss_rate% ;}}voidUdpClient::ShowHelp()const{std::cout Available commands: ;std::cout help Show this help message ;std::cout quit, exit Exit the client ;std::cout status Show connection status ;std::cout stats Show statistics ;std::cout reset Reset statistics ;std::cout ping Send ping to server ;std::cout time Get server time ;std::cout echo message Echo message to server ;std::cout file [name] Simulate file transfer ;std::cout perftest Run performance test ;std::cout any text Send custom message ;}voidUdpClient::PrintStatus()const{std::cout Client Status ;std::coutServer: server_ip_:server_port_ ;std::coutSocket: (sockfd_0?OK:Not initialized) ;std::coutConnected: (is_connected_?Yes:No) ;std::coutRunning: (is_running_?Yes:No) ;}voidUdpClient::GetStats(uint64_tsent_packets,uint64_treceived_packets,uint64_tsent_bytes,uint64_treceived_bytes)const{sent_packetspackets_sent_;received_packetspackets_received_;sent_bytesbytes_sent_;received_bytesbytes_received_;}voidUdpClient::ResetStats(){packets_sent_0;packets_received_0;bytes_sent_0;bytes_received_0;}voidUdpClient::Disconnect(){if(sockfd_0){// 發(fā)送斷開連接消息std::string disconnect_msgDISCONNECT;Send(disconnect_msg);// 關(guān)閉套接字close(sockfd_);sockfd_-1;std::coutDisconnected from serverstd::endl;}is_connected_false;is_running_false;}// 客戶端主程序intmain(intargc,char*argv[]){std::string server_ip127.0.0.1;intserver_port8080;// 解析命令行參數(shù)for(inti1;iargc;i){std::string argargv[i];if(arg-s||arg--server){if(i1argc){server_ipargv[i];}}elseif(arg-p||arg--port){if(i1argc){server_portstd::atoi(argv[i]);}}elseif(arg-h||arg--help){std::coutUDP Client Usage: ;std::cout -s, --server IP Server IP address (default: 127.0.0.1) ;std::cout -p, --port PORT Server port (default: 8080) ;std::cout -t, --test Run performance test ;std::cout -i, --interactive Run in interactive mode ;std::cout -h, --help Show this help ;return0;}elseif(arg-t||arg--test){// 性能測(cè)試模式UdpClientclient(server_ip,server_port);if(client.Init()client.Connect()){client.RunPerformanceTest();}return0;}elseif(arg-i||arg--interactive){// 交互模式默認(rèn)}}std::cout UDP Client ;std::coutConnecting to server_ip:server_port ;UdpClientclient(server_ip,server_port);if(!client.Init()){std::cerrFailed to initialize clientstd::endl;return1;}if(!client.Connect()){std::cerrFailed to connect to serverstd::endl;return1;}// 運(yùn)行交互模式client.RunInteractive();std::cout Client terminatedstd::endl;return0;}四、測(cè)試4.1 單元測(cè)試// TestUdpServer.cpp#includegtest/gtest.h#includethread#includechrono#includeUdpServer.hpp#includeUdpClient.hclassUdpServerTest:public::testing::Test{protected:voidSetUp()override{// 啟動(dòng)測(cè)試服務(wù)器test_port_9999;server_std::make_uniqueUdpServer(test_port_);ASSERT_TRUE(server_-Init());// 在后臺(tái)線程運(yùn)行服務(wù)器server_thread_std::thread([this](){server_-Run();});// 等待服務(wù)器啟動(dòng)std::this_thread::sleep_for(std::chrono::milliseconds(100));}voidTearDown()override{if(server_){server_-Stop();}if(server_thread_.joinable()){server_thread_.join();}}inttest_port_;std::unique_ptrUdpServerserver_;std::thread server_thread_;};TEST_F(UdpServerTest,BasicEcho){UdpClientclient(127.0.0.1,test_port_);ASSERT_TRUE(client.Init());std::string send_dataHello, Server!;std::string recv_data;EXPECT_TRUE(client.SendAndReceive(send_data,recv_data));EXPECT_NE(recv_data.find(Server received),std::string::npos);EXPECT_NE(recv_data.find(send_data),std::string::npos);}TEST_F(UdpServerTest,MultipleClients){constintNUM_CLIENTS5;std::vectorstd::unique_ptrUdpClientclients;std::vectorstd::threadclient_threads;for(inti0;iNUM_CLIENTS;i){autoclientstd::make_uniqueUdpClient(127.0.0.1,test_port_);ASSERT_TRUE(client-Init());clients.push_back(std::move(client));}// 并發(fā)發(fā)送消息for(inti0;iNUM_CLIENTS;i){client_threads.emplace_back([clients,i](){std::string send_dataMessage from client std::to_string(i);std::string recv_data;EXPECT_TRUE(clients[i]-SendAndReceive(send_data,recv_data,3000));});}// 等待所有線程完成for(autothread:client_threads){thread.join();}}TEST_F(UdpServerTest,LargeData){UdpClientclient(127.0.0.1,test_port_);ASSERT_TRUE(client.Init());// 發(fā)送較大數(shù)據(jù)小于64KBstd::stringlarge_data(50000,X);// 50KBstd::string recv_data;EXPECT_TRUE(client.SendAndReceive(large_data,recv_data,5000));EXPECT_GT(recv_data.size(),large_data.size());}TEST_F(UdpServerTest,Performance){UdpClientclient(127.0.0.1,test_port_);ASSERT_TRUE(client.Init());constintNUM_PACKETS100;constintPACKET_SIZE1400;// 避免分片autostart_timestd::chrono::high_resolution_clock::now();intsuccess_count0;for(inti0;iNUM_PACKETS;i){std::stringdata(PACKET_SIZE,A(i%26));std::string response;if(client.SendAndReceive(data,response,1000)){success_count;}std::this_thread::sleep_for(std::chrono::milliseconds(10));}autoend_timestd::chrono::high_resolution_clock::now();autodurationstd::chrono::duration_caststd::chrono::milliseconds(end_time-start_time);std::cout Performance Test Results: ;std::coutSuccessful exchanges: success_count/NUM_PACKETS ;std::coutTotal time: duration.count() ms ;std::coutAverage RTT: (duration.count()/(double)success_count) ms ;EXPECT_GT(success_count,NUM_PACKETS*0.9);// 90%成功率}intmain(intargc,char**argv){::testing::InitGoogleTest(argc,argv);returnRUN_ALL_TESTS();}4.2 集成測(cè)試// IntegrationTest.cpp#includeiostream#includethread#includevector#includeatomic#includeAdvancedUdpServer.hpp#includeUdpClient.hclassIntegrationTest{private:std::unique_ptrAdvancedUdpServerserver_;std::thread server_thread_;intserver_port_;public:IntegrationTest(intport8888,intworkers4):server_port_(port){// 啟動(dòng)高性能服務(wù)器server_std::make_uniqueAdvancedUdpServer(port,workers);server_-SetBufferSize(65536);server_-SetTimeout(1,0);if(!server_-Init()){throwstd::runtime_error(Failed to initialize server);}// 在后臺(tái)運(yùn)行服務(wù)器server_thread_std::thread([this](){server_-Run();});// 等待服務(wù)器啟動(dòng)std::this_thread::sleep_for(std::chrono::milliseconds(200));std::coutTest server started on port portstd::endl;}~IntegrationTest(){if(server_){server_-Stop();}if(server_thread_.joinable()){server_thread_.join();}std::coutTest server stoppedstd::endl;}voidRunLoadTest(intnum_clients,intmessages_per_client){std::cout Load Test ;std::coutClients: num_clients ;std::coutMessages per client: messages_per_client ;std::vectorstd::threadclient_threads;std::atomicinttotal_success{0};std::atomicinttotal_failures{0};autostart_timestd::chrono::high_resolution_clock::now();// 創(chuàng)建客戶端線程for(intclient_id0;client_idnum_clients;client_id){client_threads.emplace_back([this,client_id,messages_per_client,total_success,total_failures](){UdpClientclient(127.0.0.1,server_port_);if(!client.Init()){total_failuresmessages_per_client;return;}intlocal_success0;intlocal_failures0;for(intmsg_num0;msg_nummessages_per_client;msg_num){std::string messageClientstd::to_string(client_id)_Msgstd::to_string(msg_num);std::string response;if(client.SendAndReceive(message,response,1000)){local_success;// 驗(yàn)證響應(yīng)包含原始消息if(response.find(message)std::string::npos){std::cerrWarning: Invalid response from serverstd::endl;}}else{local_failures;}// 小延遲避免擁塞std::this_thread::sleep_for(std::chrono::milliseconds(10));}total_successlocal_success;total_failureslocal_failures;std::coutClient client_id: local_success/messages_per_client successfulstd::endl;});}// 等待所有客戶端完成for(autothread:client_threads){thread.join();}autoend_timestd::chrono::high_resolution_clock::now();autodurationstd::chrono::duration_caststd::chrono::milliseconds(end_time-start_time);// 輸出結(jié)果std::cout Load Test Results ;std::coutTotal messages: (num_clients*messages_per_client) ;std::coutSuccessful: total_success ;std::coutFailed: total_failures ;std::coutSuccess rate: (total_success*100.0/(num_clients*messages_per_client))% ;std::coutTotal time: duration.count() ms ;std::coutThroughput: (total_success*1000.0/duration.count()) messages/second ;// 驗(yàn)證至少95%成功率doublesuccess_ratetotal_success*100.0/(num_clients*messages_per_client);if(success_rate95.0){std::cout ? Load test PASSEDstd::endl;}else{std::cout ? Load test FAILED (success rate below 95%)std::endl;}}voidRunStressTest(){std::cout Stress Test ;constintNUM_CLIENTS10;constintMESSAGES_PER_CLIENT1000;constintMESSAGE_SIZE1000;// 1KBstd::vectorstd::threadclient_threads;std::atomicuint64_ttotal_bytes_sent{0};std::atomicuint64_ttotal_bytes_received{0};autostart_timestd::chrono::high_resolution_clock::now();for(inti0;iNUM_CLIENTS;i){client_threads.emplace_back([this,i,total_bytes_sent,total_bytes_received](){UdpClientclient(127.0.0.1,server_port_);if(!client.Init()){return;}// 準(zhǔn)備大消息std::stringlarge_message(MESSAGE_SIZE,A(i%26));uint64_tclient_bytes_sent0;uint64_tclient_bytes_received0;for(intj0;jMESSAGES_PER_CLIENT;j){// 修改消息內(nèi)容large_message[0]0(j%10);std::string response;if(client.SendAndReceive(large_message,response,500)){client_bytes_sentlarge_message.size();client_bytes_receivedresponse.size();}// 更短的延遲以增加壓力if(j%1000){std::this_thread::sleep_for(std::chrono::microseconds(100));}}total_bytes_sentclient_bytes_sent;total_bytes_receivedclient_bytes_received;std::coutStress client i completedstd::endl;});}for(autothread:client_threads){thread.join();}autoend_timestd::chrono::high_resolution_clock::now();autodurationstd::chrono::duration_caststd::chrono::milliseconds(end_time-start_time);std::cout Stress Test Results ;std::coutTotal data sent: (total_bytes_sent/1024.0/1024.0) MB ;std::coutTotal data received: (total_bytes_received/1024.0/1024.0) MB ;std::coutTotal time: duration.count() ms ;if(duration.count()0){doublesend_throughput(total_bytes_sent*8.0)/(duration.count()*1000.0);// Mbpsdoublereceive_throughput(total_bytes_received*8.0)/(duration.count()*1000.0);// Mbpsstd::coutSend throughput: send_throughput Mbps ;std::coutReceive throughput: receive_throughput Mbps ;std::coutTotal throughput: (send_throughputreceive_throughput) Mbps ;}if(total_bytes_sent0){std::cout ? Stress test completed successfullystd::endl;}}};intmain(){try{std::cout UDP System Integration Test ;IntegrationTesttest(8888,4);// 運(yùn)行負(fù)載測(cè)試test.RunLoadTest(5,100);// 運(yùn)行壓力測(cè)試test.RunStressTest();std::cout All tests completed ;}catch(conststd::exceptione){std::cerrTest failed: e.what()std::endl;return1;}return0;}4.3 網(wǎng)絡(luò)測(cè)試工具// NetworkTestTool.cpp#includeiostream#includeiomanip#includevector#includemap#includecmath#includeUdpClient.hclassNetworkTestTool{private:std::string server_ip_;intserver_port_;public:NetworkTestTool(conststd::stringip,intport):server_ip_(ip),server_port_(port){}voidRunLatencyTest(intnum_packets100){std::cout Latency Test ;std::coutServer: server_ip_:server_port_ ;std::coutPackets: num_packets ;UdpClientclient(server_ip_,server_port_);if(!client.Init()){std::cerrFailed to initialize clientstd::endl;return;}std::vectordoublelatencies;intsuccessful_packets0;for(inti0;inum_packets;i){// 準(zhǔn)備包含時(shí)間戳的消息autosend_timestd::chrono::high_resolution_clock::now();uint64_tsend_nsstd::chrono::duration_caststd::chrono::nanoseconds(send_time.time_since_epoch()).count();std::string messagePING_std::to_string(i)_std::to_string(send_ns);std::string response;if(client.SendAndReceive(message,response,1000)){autorecv_timestd::chrono::high_resolution_clock::now();uint64_trecv_nsstd::chrono::duration_caststd::chrono::nanoseconds(recv_time.time_since_epoch()).count();// 計(jì)算往返時(shí)間doublertt_nsstatic_castdouble(recv_ns-send_ns);doublertt_msrtt_ns/1000000.0;latencies.push_back(rtt_ms);successful_packets;if((i1)%100){std::coutSent (i1) packets...std::endl;}}else{std::coutPacket i loststd::endl;}// 等待以避免擁塞std::this_thread::sleep_for(std::chrono::milliseconds(100));}// 計(jì)算統(tǒng)計(jì)信息if(!latencies.empty()){doublesum0;doublemin_latencylatencies[0];doublemax_latencylatencies[0];for(doublelatency:latencies){sumlatency;min_latencystd::min(min_latency,latency);max_latencystd::max(max_latency,latency);}doubleaveragesum/latencies.size();// 計(jì)算標(biāo)準(zhǔn)差doublevariance0;for(doublelatency:latencies){variance(latency-average)*(latency-average);}variance/latencies.size();doublestddevstd::sqrt(variance);// 計(jì)算百分位數(shù)std::sort(latencies.begin(),latencies.end());doublep50latencies[latencies.size()*0.5];doublep90latencies[latencies.size()*0.9];doublep95latencies[latencies.size()*0.95];doublep99latencies[latencies.size()*0.99];// 輸出結(jié)果std::cout Latency Test Results ;std::coutPackets sent: num_packets ;std::coutPackets received: successful_packets ;std::coutPacket loss: std::fixedstd::setprecision(2)((num_packets-successful_packets)*100.0/num_packets)% ;std::cout Latency statistics (ms): ;std::cout Minimum: std::fixedstd::setprecision(3)min_latency ;std::cout Maximum: max_latency ;std::cout Average: average ;std::cout Std Dev: stddev ;std::cout 50th percentile: p50 ;std::cout 90th percentile: p90 ;std::cout 95th percentile: p95 ;std::cout 99th percentile: p99 ;// 顯示直方圖DisplayHistogram(latencies);}}voidDisplayHistogram(conststd::vectordoubledata){if(data.empty())return;doublemin_val*std::min_element(data.begin(),data.end());doublemax_val*std::max_element(data.begin(),data.end());constintNUM_BINS10;doublebin_width(max_val-min_val)/NUM_BINS;std::vectorintbins(NUM_BINS,0);for(doublevalue:data){intbin_indexstatic_castint((value-min_val)/bin_width);if(bin_indexNUM_BINS)bin_index--;// 處理邊界情況bins[bin_index];}std::cout Latency distribution: ;for(inti0;iNUM_BINS;i){doublebin_startmin_vali*bin_width;doublebin_endbin_startbin_width;std::coutstd::fixedstd::setprecision(1) std::setw(6)bin_start - std::setw(6)bin_end ms: std::string(bins[i]*50/data.size(),#) (bins[i]) ;}}voidRunBandwidthTest(intduration_sec10,intpacket_size1400){std::cout Bandwidth Test ;std::coutDuration: duration_sec seconds ;std::coutPacket size: packet_size bytes ;UdpClientclient(server_ip_,server_port_);if(!client.Init()){std::cerrFailed to initialize clientstd::endl;return;}std::vectorcharpacket_data(packet_size,B);autostart_timestd::chrono::steady_clock::now();autoend_timestart_timestd::chrono::seconds(duration_sec);uint64_ttotal_packets0;uint64_ttotal_bytes0;uint64_tsuccessful_responses0;std::coutTesting bandwidth... ;while(std::chrono::steady_clock::now()end_time){// 發(fā)送數(shù)據(jù)包if(client.Send(packet_data.data(),packet_size)){total_packets;total_bytespacket_size;}// 嘗試接收響應(yīng)非阻塞std::string response;if(client.Receive(response,10)){// 10ms超時(shí)successful_responses;}// 控制發(fā)送速率約1000 packets/secondstd::this_thread::sleep_for(std::chrono::microseconds(900));}autoactual_endstd::chrono::steady_clock::now();autoactual_durationstd::chrono::duration_caststd::chrono::milliseconds(actual_end-start_time);// 輸出結(jié)果std::cout Bandwidth Test Results ;std::coutActual duration: actual_duration.count() ms ;std::coutPackets sent: total_packets ;std::coutTotal data sent: (total_bytes/1024.0/1024.0) MB ;std::coutResponses received: successful_responses ;if(actual_duration.count()0){doublepackets_per_sectotal_packets*1000.0/actual_duration.count();doublebandwidth_mbps(total_bytes*8.0)/(actual_duration.count()*1000.0);std::coutSend rate: packets_per_sec packets/second ;std::coutBandwidth: bandwidth_mbps Mbps ;std::coutResponse rate: (successful_responses*1000.0/actual_duration.count()) packets/second ;}doubleloss_rate0;if(total_packets0){loss_rate(1.0-(successful_responses/(double)total_packets))*100.0;std::coutEstimated loss rate: std::fixedstd::setprecision(2)loss_rate% ;}}};intmain(intargc,char*argv[]){std::string server_ip127.0.0.1;intserver_port8080;std::string test_typelatency;// 解析命令行參數(shù)for(inti1;iargc;i){std::string argargv[i];if(arg-s||arg--server){if(i1argc)server_ipargv[i];}elseif(arg-p||arg--port){if(i1argc)server_portstd::atoi(argv[i]);}elseif(arg-t||arg--test){if(i1argc)test_typeargv[i];}elseif(arg-h||arg--help){std::coutNetwork Test Tool ;std::coutUsage: argv[0] [options] ;std::coutOptions: ;std::cout -s, --server IP Server IP address ;std::cout -p, --port PORT Server port ;std::cout -t, --test TYPE Test type (latency|bandwidth) ;std::cout -h, --help Show this help ;return0;}}NetworkTestTooltester(server_ip,server_port);if(test_typelatency){tester.RunLatencyTest();}elseif(test_typebandwidth){tester.RunBandwidthTest();}else{std::cerrUnknown test type: test_typestd::endl;std::cerrAvailable types: latency, bandwidthstd::endl;return1;}return0;}五、源代碼5.1 Log.hpp - 日志系統(tǒng)#ifndefLOG_HPP#defineLOG_HPP#includeiostream#includefstream#includestring#includesstream#includeiomanip#includectime#includemutex#includememory// 日志級(jí)別enumclassLogLevel{DEBUG,INFO,WARN,ERROR,FATAL};classLogger{private:staticstd::shared_ptrLoggerinstance_;std::ofstream log_file_;LogLevel min_level_;std::mutex log_mutex_;boolconsole_output_;// 私有構(gòu)造函數(shù)Logger():min_level_(LogLevel::INFO),console_output_(true){}public:// 刪除拷貝構(gòu)造函數(shù)和賦值運(yùn)算符Logger(constLogger)delete;Loggeroperator(constLogger)delete;// 獲取單例實(shí)例staticLoggerInstance(){staticstd::shared_ptrLoggerinstance(newLogger());return*instance;}// 初始化日志系統(tǒng)boolInit(conststd::stringfilename,LogLevel min_levelLogLevel::INFO,boolconsoletrue){std::lock_guardstd::mutexlock(log_mutex_);min_level_min_level;console_output_console;if(!filename.empty()){log_file_.open(filename,std::ios::app);if(!log_file_.is_open()){std::cerrFailed to open log file: filenamestd::endl;returnfalse;}}returntrue;}// 設(shè)置日志級(jí)別voidSetLevel(LogLevel level){std::lock_guardstd::mutexlock(log_mutex_);min_level_level;}// 啟用/禁用控制臺(tái)輸出voidEnableConsole(boolenable){std::lock_guardstd::mutexlock(log_mutex_);console_output_enable;}// 記錄日志voidLog(LogLevel level,conststd::stringmessage,constchar*filenullptr,intline0){if(levelmin_level_){return;}std::lock_guardstd::mutexlock(log_mutex_);// 獲取當(dāng)前時(shí)間autonowstd::chrono::system_clock::now();autonow_timestd::chrono::system_clock::to_time_t(now);autonow_msstd::chrono::duration_caststd::chrono::milliseconds(now.time_since_epoch())%1000;// 格式化時(shí)間std::tm*tm_infostd::localtime(now_time);chartime_buffer[80];std::strftime(time_buffer,sizeof(time_buffer),%Y-%m-%d %H:%M:%S,tm_info);// 日志級(jí)別字符串constchar*level_str;switch(level){caseLogLevel::DEBUG:level_strDEBUG;break;caseLogLevel::INFO:level_strINFO;break;caseLogLevel::WARN:level_strWARN;break;caseLogLevel::ERROR:level_strERROR;break;caseLogLevel::FATAL:level_strFATAL;break;}// 構(gòu)建日志消息std::stringstream ss;ss[time_buffer.std::setfill(0)std::setw(3)now_ms.count()] [level_str] ;if(file!nullptr){ss[file:line] ;}ssmessage;std::string log_messagess.str();// 輸出到控制臺(tái)if(console_output_){std::ostreamstream(levelLogLevel::WARN)?std::cerr:std::cout;streamlog_messagestd::endl;if(levelLogLevel::FATAL){streamFatal error, terminating...std::endl;}}// 輸出到文件if(log_file_.is_open()){log_file_log_messagestd::endl;log_file_.flush();if(levelLogLevel::FATAL){log_file_Fatal error, terminating...std::endl;log_file_.flush();}}// 如果是致命錯(cuò)誤終止程序if(levelLogLevel::FATAL){std::exit(EXIT_FAILURE);}}// 關(guān)閉日志voidClose(){std::lock_guardstd::mutexlock(log_mutex_);if(log_file_.is_open()){log_file_.close();}}~Logger(){Close();}};// 日志宏#defineLOG_DEBUG(msg)Logger::Instance().Log(LogLevel::DEBUG,msg,__FILE__,__LINE__)#defineLOG_INFO(msg)Logger::Instance().Log(LogLevel::INFO,msg,__FILE__,__LINE__)#defineLOG_WARN(msg)Logger::Instance().Log(LogLevel::WARN,msg,__FILE__,__LINE__)#defineLOG_ERROR(msg)Logger::Instance().Log(LogLevel::ERROR,msg,__FILE__,__LINE__)#defineLOG_FATAL(msg)Logger::Instance().Log(LogLevel::FATAL,msg,__FILE__,__LINE__)#endif// LOG_HPP5.2 Makefile - 構(gòu)建系統(tǒng)# Makefile for UDP Network System # Compiler and flags CXX g CXXFLAGS -stdc11 -Wall -Wextra -O2 -pthread DEBUG_FLAGS -g -DDEBUG RELEASE_FLAGS -O3 -DNDEBUG # Directories SRC_DIR src OBJ_DIR obj BIN_DIR bin INC_DIR include # Source files SERVER_SRCS $(SRC_DIR)/UdpServer.cpp $(SRC_DIR)/Main.cpp $(SRC_DIR)/Log.cpp CLIENT_SRCS $(SRC_DIR)/UdpClient.cpp TEST_SRCS $(SRC_DIR)/TestUdpServer.cpp INTEGRATION_SRCS $(SRC_DIR)/IntegrationTest.cpp NETTEST_SRCS $(SRC_DIR)/NetworkTestTool.cpp # Object files SERVER_OBJS $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SERVER_SRCS)) CLIENT_OBJS $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(CLIENT_SRCS)) TEST_OBJS $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(TEST_SRCS)) INTEGRATION_OBJS $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(INTEGRATION_SRCS)) NETTEST_OBJS $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(NETTEST_SRCS)) # Executables SERVER_EXE $(BIN_DIR)/udp_server CLIENT_EXE $(BIN_DIR)/udp_client TEST_EXE $(BIN_DIR)/test_server INTEGRATION_EXE $(BIN_DIR)/integration_test NETTEST_EXE $(BIN_DIR)/network_test # Include paths INCLUDES -I$(INC_DIR) # Libraries LIBS -lpthread TEST_LIBS $(LIBS) -lgtest -lgtest_main # Default target all: directories server client # Create directories directories: mkdir -p $(OBJ_DIR) $(BIN_DIR) # Server build server: $(SERVER_EXE) $(SERVER_EXE): $(SERVER_OBJS) $(CXX) $(CXXFLAGS) $(INCLUDES) $^ -o $ $(LIBS) # Client build client: $(CLIENT_EXE) $(CLIENT_EXE): $(CLIENT_OBJS) $(CXX) $(CXXFLAGS) $(INCLUDES) $^ -o $ $(LIBS) # Test build test: $(TEST_EXE) $(TEST_EXE): $(TEST_OBJS) $(CXX) $(CXXFLAGS) $(INCLUDES) $^ -o $ $(TEST_LIBS) # Integration test build integration: $(INTEGRATION_EXE) $(INTEGRATION_EXE): $(INTEGRATION_OBJS) $(CXX) $(CXXFLAGS) $(INCLUDES) $^ -o $ $(LIBS) # Network test tool build nettest: $(NETTEST_EXE) $(NETTEST_EXE): $(NETTEST_OBJS) $(CXX) $(CXXFLAGS) $(INCLUDES) $^ -o $ $(LIBS) # Compile source files $(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp $(CXX) $(CXXFLAGS) $(INCLUDES) -c $ -o $ # Debug build debug: CXXFLAGS $(DEBUG_FLAGS) debug: all # Release build release: CXXFLAGS $(RELEASE_FLAGS) release: all # Static analysis with cppcheck check: cppcheck --enableall --suppressmissingIncludeSystem $(SRC_DIR) $(INC_DIR) # Run tests run-test: test $(TEST_EXE) run-integration: integration $(INTEGRATION_EXE) # Clean build files clean: rm -rf $(OBJ_DIR) $(BIN_DIR) rm -f *.log # Install system-wide (requires root) install: release cp $(SERVER_EXE) /usr/local/bin/udp_server cp $(CLIENT_EXE) /usr/local/bin/udp_client chmod x /usr/local/bin/udp_server /usr/local/bin/udp_client # Uninstall uninstall: rm -f /usr/local/bin/udp_server /usr/local/bin/udp_client # Run server run-server: server $(SERVER_EXE) -p 8080 # Run client run-client: client $(CLIENT_EXE) -s 127.0.0.1 -p 8080 # Run network test run-nettest: nettest $(NETTEST_EXE) -s 127.0.0.1 -p 8080 -t latency # Generate documentation doc: doxygen Doxyfile # Help help: echo Available targets: echo all - Build server and client (default) echo server - Build server only echo client - Build client only echo test - Build and run unit tests echo integration - Build integration tests echo nettest - Build network test tool echo debug - Build with debug flags echo release - Build with release flags echo check - Run static analysis echo run-test - Run unit tests echo run-integration - Run integration tests echo clean - Remove build files echo install - Install system-wide echo uninstall - Uninstall echo run-server - Run server on port 8080 echo run-client - Run client connecting to localhost:8080 echo run-nettest - Run network latency test echo doc - Generate documentation echo help - Show this help .PHONY: all directories server client test integration nettest debug release check run-test run-integration clean install uninstall run-server run-client run-nettest doc help5.3 完整的UdpServer.hpp#ifndefUDPSERVER_HPP#defineUDPSERVER_HPP#includeiostream#includestring#includecstring#includecstdlib#includeunistd.h#includearpa/inet.h#includesys/socket.h#includesys/types.h#includenetinet/in.h#includethread#includevector#includememory#includeatomic#includefunctional#includequeue#includemutex#includecondition_variable#includeLog.hppclassUdpServer{protected:intport_;// 服務(wù)器端口intsockfd_;// 套接字描述符std::atomicboolis_running_;// 服務(wù)器運(yùn)行狀態(tài)structsockaddr_inserver_addr_;// 服務(wù)器地址結(jié)構(gòu)structsockaddr_inclient_addr_;// 客戶端地址結(jié)構(gòu)socklen_t client_addr_len_;// 客戶端地址長(zhǎng)度// 服務(wù)器配置參數(shù)size_t buffer_size_;// 緩沖區(qū)大小inttimeout_sec_;// 接收超時(shí)時(shí)間(秒)inttimeout_usec_;// 接收超時(shí)時(shí)間(微秒)boolreuse_addr_;// 是否重用地址public:// 構(gòu)造函數(shù)explicitUdpServer(intport8080);// 析構(gòu)函數(shù)virtual~UdpServer();// 禁止拷貝構(gòu)造和賦值UdpServer(constUdpServer)delete;UdpServeroperator(constUdpServer)delete;// 初始化服務(wù)器virtualboolInit();// 運(yùn)行服務(wù)器virtualvoidRun();// 停止服務(wù)器virtualvoidStop();// 設(shè)置配置參數(shù)voidSetBufferSize(size_t size){buffer_size_size;}voidSetTimeout(intsec,intusec0){timeout_sec_sec;timeout_usec_usec;}voidSetReuseAddr(boolreuse){reuse_addr_reuse;}// 獲取服務(wù)器信息intGetPort()const{returnport_;}boolIsRunning()const{returnis_running_;}protected:// 創(chuàng)建套接字virtualboolCreateSocket();// 綁定地址virtualboolBindAddress();// 設(shè)置套接字選項(xiàng)virtualboolSetSocketOptions();// 處理接收到的數(shù)據(jù)virtualvoidProcessData(constchar*data,ssize_t len,conststructsockaddr_inclient_addr);// 發(fā)送響應(yīng)virtualboolSendResponse(constchar*data,ssize_t len,conststructsockaddr_inclient_addr);// 清理資源virtualvoidCleanup();};// 高級(jí)UDP服務(wù)器帶線程池classAdvancedUdpServer:publicUdpServer{private:std::vectorstd::threadworker_threads_;std::atomicintthread_count_;intmax_workers_;// 線程池和工作隊(duì)列structTask{std::vectorchardata;structsockaddr_inclient_addr;time_t receive_time;Task(conststd::vectorchard,conststructsockaddr_inaddr):data(d),client_addr(addr),receive_time(time(nullptr)){}};std::queueTasktask_queue_;std::mutex queue_mutex_;std::condition_variable queue_cv_;std::atomicboolworkers_running_;public:AdvancedUdpServer(intport8080,intmax_workers4);~AdvancedUdpServer()override;boolInit()override;voidRun()override;voidStop()override;// 獲取線程池狀態(tài)intGetActiveWorkers()const{returnthread_count_;}size_tGetQueueSize()const{returntask_queue_.size();}private:voidWorkerThread(intthread_id);voidProcessTask(constTasktask,intthread_id);// 重寫基類方法boolSetSocketOptions()override;voidProcessData(constchar*data,ssize_t len,conststructsockaddr_inclient_addr)override;// 任務(wù)調(diào)度voidAddTask(conststd::vectorchardata,conststructsockaddr_inclient_addr);};#endif// UDPSERVER_HPP5.4 完整的Main.cpp#includeiostream#includecsignal#includecstdlib#includememory#includegetopt.h#includeUdpServer.hpp#includeAdvancedUdpServer.hpp// 全局服務(wù)器指針用于信號(hào)處理std::unique_ptrUdpServerg_server;// 信號(hào)處理函數(shù)voidSignalHandler(intsignal){std::cout Received signal signal, shutting down...std::endl;if(g_server){g_server-Stop();}}// 顯示使用幫助voidShowUsage(constchar*program_name){std::coutUDP Server v1.0 - High Performance UDP Server Implementation ;std::coutBuild Date: __DATE__ __TIME__ ;std::coutUsage: program_name [options] ;std::coutOptions: ;std::cout -p, --port PORT Server port (default: 8080) ;std::cout -b, --buffer SIZE Buffer size in bytes (default: 4096) ;std::cout -t, --timeout SEC Receive timeout in seconds (default: 5) ;std::cout -w, --workers NUM Number of worker threads (default: 1) ;std::cout -a, --advanced Use advanced server with thread pool ;std::cout -r, --no-reuse Disable address reuse ;std::cout -v, --verbose Enable verbose logging ;std::cout -d, --daemon Run as daemon ;std::cout -c, --config FILE Load configuration from file ;std::cout -h, --help Show this help message ;std::cout Examples: ;std::cout program_name -p 9000 -b 8192 ;std::cout program_name --port 8080 --workers 4 --advanced ;std::cout program_name --daemon --config /etc/udp-server.conf ;}// 服務(wù)器配置結(jié)構(gòu)structServerConfig{intport8080;size_t buffer_size4096;inttimeout_se
版權(quán)聲明: 本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)聯(lián)系我們進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

電商網(wǎng)站制作價(jià)格wordpress全站301

電商網(wǎng)站制作價(jià)格,wordpress全站301,網(wǎng)站怎么做頁(yè)游,青州住房和城鄉(xiāng)建設(shè)網(wǎng)站第一章#xff1a;為什么頂尖量子計(jì)算工程師都在用Cirq函數(shù)提示#xff1f;在量子計(jì)算領(lǐng)域#xff0c;精確控

2026/01/23 00:21:01

北海網(wǎng)站制作公司wordpress comment_status

北海網(wǎng)站制作公司,wordpress comment_status,網(wǎng)絡(luò)營(yíng)銷的基本職能有哪些,東莞常平核酸檢測(cè)點(diǎn)跨領(lǐng)域推薦中的協(xié)同過濾#xff1a;從理論到實(shí)戰(zhàn)的深度探索你有沒有這樣的經(jīng)歷#xff1f

2026/01/23 08:37:01