`
famoushz
  • 浏览: 2966265 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

还是七猫的文章。七猫对服务器设计真的很值得学习[ACE高效PROACTOR编程框架七ServerExample]摘自七猫

阅读更多
最有说服力了!
先汗一个!

cpp 代码
 
  1. #pragma once  
  2. #include <errno.h>  
  3. #include <sys/epoll.h>  
  4. #include <sys/types.h>  
  5. #include <sys/socket.h>  
  6. #include <fcntl.h>  
  7. #include <unistd.h>  
  8. #include <string.h>  
  9. #include "log.h"  
  10.   
  11. #ifndef EPOLL_SIZE  
  12. #define EPOLL_SIZE 4096  
  13. #define EPOLL_CONTEXT_SIZE (4096+256)  
  14. #endif  
  15.   
  16. typedef void * EPollerContext;  
  17. class Epoller  
  18. {  
  19. public:  
  20. Epoller(){}  
  21. virtual ~Epoller(){}  
  22. bool create()  
  23. {  
  24.  memset(_contexts,0,sizeof(_contexts));  
  25.  _handle=epoll_create(EPOLL_SIZE);  
  26.  if(_handle==-1)  
  27.  {  
  28.   glog.log(__FUNCTION__,"Epoll create error,errno is %d",errno);  
  29.   return false;  
  30.  }  
  31.  else  
  32.   return true;  
  33. }  
  34. void handle_events()  
  35. {  
  36.  for(int i=0;i<_lastntfd;i++)  
  37.  {  
  38.   on_event(_events[i].data.fd,_events[i].events);  
  39.  }  
  40. }  
  41. int get_online_users()  
  42. {  
  43.  int result=0;  
  44.  for(int i=0;i<EPOLL_CONTEXT_SIZE;i++)  
  45.  {  
  46.   if(_contexts[i]!=0)  
  47.    result++;  
  48.  }  
  49.  return result;  
  50. }  
  51. public:  
  52. bool add(int fd,unsigned int events)  
  53. {  
  54.  epoll_event polevt;  
  55.  polevt.events=events;  
  56.  polevt.data.fd=fd;  
  57.  return ctl(EPOLL_CTL_ADD,fd,polevt)==0;  
  58. }  
  59. bool del(int fd,unsigned int events)  
  60. {  
  61.  epoll_event polevt;  
  62.  polevt.events=events;  
  63.  polevt.data.fd=fd;  
  64.  return ctl(EPOLL_CTL_DEL,fd,polevt)==0;  
  65. }  
  66. bool modify(int fd,unsigned int events)  
  67. {  
  68.  epoll_event polevt;  
  69.  polevt.events=events;  
  70.  polevt.data.fd=fd;  
  71.  return ctl(EPOLL_CTL_MOD,fd,polevt)==0;  
  72. }  
  73. int poll(int timeout=5000)  
  74. {  
  75.  _lastntfd=epoll_wait(_handle,_events,EPOLL_SIZE,timeout);  
  76.  return _lastntfd;  
  77. }  
  78. protected:  
  79. int ctl(int op, int fd, struct epoll_event &event)  
  80. {  
  81.  int ret=epoll_ctl(_handle,op,fd,&event);  
  82.  if(ret!=0)  
  83.  {  
  84.   glog.log(__FUNCTION__,"epoll_ctl fail,op is %d,fd is %d,errno is %d",op,fd,errno);  
  85.  }  
  86.  return ret;  
  87. }  
  88. protected:  
  89. static bool setnonblocking(int sock)  
  90. {  
  91.  int opts;  
  92.  opts=fcntl(sock,F_GETFL);  
  93.  if(opts<0)  
  94.   opts=O_NONBLOCK;  
  95.  else  
  96.   opts = opts|O_NONBLOCK;  
  97.  if(fcntl(sock,F_SETFL,opts)<0)  
  98.  {  
  99.   glog.log(__FUNCTION__,"setnoblock error");  
  100.   return false;  
  101.  }  
  102.  else  
  103.   return true;  
  104. }  
  105.   
  106. static bool setreuseport(int sock)  
  107. {  
  108.  int on=1;  
  109.  int ret=setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof(int));  
  110.  return ret!=-1;  
  111. }  
  112.   
  113.   
  114.   
  115. protected:  
  116. virtual void on_event(int fd,int events){}  
  117. private:  
  118. int _handle;  
  119. epoll_event _events[EPOLL_SIZE];  
  120. int _lastntfd;  
  121. protected:  
  122. EPollerContext _contexts[EPOLL_CONTEXT_SIZE];  
  123. EPollerContext get_context(int value)  
  124. {  
  125.  return _contexts[value];  
  126. }  
  127. bool set_context(int value,EPollerContext context)  
  128. {  
  129.  _contexts[value]=context;  
  130. }  
  131. };  
  132.   
  133.   
  134.   
  135.   
  136.   
  137.   
  138.   
  139.   
  140. class ExampleServer : public Epoller  
  141. {  
  142. public:  
  143. bool init();  
  144. void fini();  
  145. void check_timeout();  
  146. protected:  
  147. void on_event(int fd,int events);  
  148. private:  
  149. void add_newsock(int sockvalue);  
  150. void remove_sock(int sockvalue);  
  151. private:  
  152. int _listen_handler;  
  153. };  
  154.   
  155.   
  156.   
  157.   
  158.   
  159. #include <sys/types.h>  
  160. #include <sys/socket.h>  
  161. #include <netinet/in.h>  
  162. #include "server.h"  
  163. #include "clientmanager.h"  
  164.   
  165. bool ExampleServer::init()  
  166. {  
  167. this->create();  
  168. _listen_handler=socket(AF_INET,SOCK_STREAM,0);  
  169. setnonblocking(_listen_handler);  
  170. setreuseport(_listen_handler);  
  171. sockaddr_in serveraddr;  
  172. memset(&serveraddr,0,sizeof(serveraddr));  
  173. serveraddr.sin_family = AF_INET;  
  174. serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);  
  175. serveraddr.sin_port=htons(ITEMLIST_SERVER_PORT);  
  176. bind(_listen_handler,(sockaddr *)&serveraddr, sizeof(serveraddr));  
  177. listen(_listen_handler,ITEMCOMMENT_SERVER_LISTEN_BACKLOG);  
  178. this->add(_listen_handler,EPOLLIN|EPOLLOUT);  
  179. this->set_context(_listen_handler,0);  
  180. }  
  181.   
  182. void ExampleServer::fini()  
  183. {  
  184. close(_listen_handler);  
  185. }  
  186.   
  187. void ExampleServer::add_newsock(int sockvalue)  
  188. {  
  189. if(sockvalue>EPOLL_CONTEXT_SIZE)  
  190. {  
  191.  glog.log(__FUNCTION__,"newsock is %d,> %d",sockvalue,EPOLL_CONTEXT_SIZE);  
  192.  close(sockvalue);  
  193.  return;  
  194. }  
  195.   
  196. ClientSession *newsession=gClientManager.alloc_client_session(sockvalue);  
  197. if(newsession==NULL)  
  198. {  
  199.  close(sockvalue);  
  200.  return;  
  201. }  
  202. if(add(sockvalue,EPOLLIN|EPOLLOUT))  
  203. {  
  204.  this->set_context(sockvalue,newsession);  
  205. }  
  206. else  
  207. {  
  208.  gClientManager.release_client(newsession);  
  209.  close(sockvalue);       
  210. }  
  211. }  
  212.   
  213. void ExampleServer::remove_sock(int sockvalue)  
  214. {  
  215. this->del(sockvalue,0);  
  216. close(sockvalue);  
  217. ClientSession *client=(ClientSession *)this->get_context(sockvalue);  
  218. if(client)  
  219. {  
  220.  gClientManager.release_client(client);  
  221. }  
  222. this->set_context(sockvalue,0);  
  223. }  
  224.   
  225. void ExampleServer::on_event(int fd,int events)  
  226. {  
  227. if(fd==_listen_handler)  
  228. {  
  229.  sockaddr_in sa;  
  230.  memset(&sa,0,sizeof(sa));  
  231.  socklen_t salen=sizeof(sa);  
  232.  int newsock=accept(_listen_handler,(sockaddr *)&sa,&salen);  
  233.  if(newsock>0)  
  234.  {  
  235.   add_newsock(newsock);  
  236.  }  
  237. }  
  238. else  
  239. {  
  240.  ClientSession *client=(ClientSession *)this->get_context(fd);  
  241.  if(client!=NULL)  
  242.  {  
  243.   int newevents=client->handle_events(fd,events);  
  244.   if(newevents==0)  
  245.   {  
  246.    remove_sock(fd);  
  247.   }  
  248.   else  
  249.    this->modify(fd,newevents);  
  250.  }  
  251. }  
  252. }  
  253.   
  254.   
  255. void ExampleServer::check_timeout()  
  256. {  
  257. unsigned int curtime=time(NULL);  
  258. for(int i=0;i<EPOLL_SIZE+256;i++)  
  259. {  
  260.  ClientSession *client=(ClientSession *)this->get_context(i);  
  261.  if(client!=NULL)  
  262.  {  
  263.   if(curtime-client->get_last_io_time()>ITEMINDEX_SERVER_MAX_TIMEOUT)  
  264.   {  
  265.    remove_sock(i);  
  266.   }  
  267.  }  
  268. }  
  269. }  
分享到:
评论

相关推荐

    ACE_Proactor网络通信示例代码

    ACE_Proactor是ACE库中的一个核心组件,它提供了一种异步事件处理机制,使得开发者可以编写非阻塞的、高性能的网络应用。这个压缩包包含的是一组使用ACE_Proactor实现TCP通信的示例代码,我们可以从这些文件中学习到...

    Windows下采用IOCP实现的ACE的Proactor框架剖析

    **Windows下的IOCP(I/O完成端口)与ACE Proactor框架** IOCP(I/O完成端口,Input/Output Completion Port)是Windows操作系统提供的一种高效、可扩展的异步I/O模型。它允许应用程序处理大量的并发I/O操作,特别...

    ACE_Proactor TCP协议通信示例代码

    ACE_Proactor是一个高级事件处理库,它为C++程序员提供了异步I/O操作的抽象,包括TCP协议的网络通信。这个示例代码是关于...通过理解和应用这些示例代码,你可以学习到如何使用ACE库来构建高效、健壮的TCP通信系统。

    ACE通用服务器ace server

    "ACE通用服务器ace server"是一个基于ACE库构建的服务器架构,它涵盖了两种核心的设计模式:Reactor和Proactor。这两个模式在并发编程和网络服务领域中具有重要地位,特别是对于高性能、高并发的服务器开发至关重要...

    对ACE的Proactor通讯模式的全面封装

    ACE Proactor模式适用于高并发、低延迟的应用场景,如实时交易系统、大规模在线游戏服务器、分布式计算等。封装后的接口使其更易于在这些领域中快速开发和部署。 7. **注意事项** 尽管封装简化了使用,但理解异步...

    C++网络编程(卷2) 基于ACE和框架的系统化复用

    《C++网络编程(卷2) 基于ACE和框架的系统化复用》是深入探讨C++在网络编程领域的经典之作,尤其注重利用ACE框架实现高效、可复用的系统设计。这本书主要涵盖了以下几个核心知识点: 1. **ACE框架**:ACE(Adaptive ...

    ACE技术内幕:深入解析ACE架构设计与实现原理

    《ace技术内幕:深入解析ace架构设计与实现原理》从构架模式、编程示例和源代码3个维度系统地对经典网络框架ace(adaptivemunicationenvironment)的架构设计和实现原理进行了深入分析,它能解决4个方面的问题:,...

    C++网络编程+卷1,2+基于ACE和框架的系统化复用

    5. **网络编程实战**:通过实例演示如何使用ACE解决实际问题,如服务器端的设计、客户端的实现、异常处理等。 6. **性能优化和测试**:讨论网络应用的性能评估和优化策略,以及如何进行压力测试。 阅读这两卷书籍...

    ACE Reactor 和proactor 通信方式两套代码

    本人学习ACE 时候写的关于两种通信方式的实例代码,我把三个连写都写在了一个文件,根据需要注释掉其他的就行。 ACE用于开发通信程序非常方便,尤其相对于WinSock 来说,可以省很多代码,普通程序员也更容易理解

    ACE技术文档及服务器客户端完整例子

    ACE(Adaptive Communication Environment)是一种跨平台的网络编程框架,专为分布式实时和嵌入式系统设计。这个压缩包包含了关于ACE技术的详尽文档和实际应用的例子,可以帮助开发者深入理解并有效地使用ACE进行...

    C++网络编程 卷1 卷2 ACE程序员指南 带详细目录

    这套书籍深入探讨了如何使用C++进行高效的网络编程,特别是利用ACE库来简化复杂性的处理。以下是这些书籍中的核心知识点: 1. **C++网络编程 卷1 - 运用ACE和模式消除复杂性**: - **ACE库介绍**:ACE是一个跨平台...

    网络编程+卷2+基于ACE和框架的系统化复用

    《网络编程+卷2+基于ACE和框架的系统化复用》是一本深入探讨网络编程技术的书籍,尤其关注如何利用ACE(Adaptive Communication Environment)框架实现高效、可靠的系统化复用。ACE是一个开源的C++库,专门设计用于...

    ACE-5.6.zip ACE5.6官网源码

    1. **ACE框架**:ACE是一个开源的C++库,设计用于解决分布式系统和并发编程中的复杂性问题。它提供了许多预构建的组件,如线程管理、信号处理、事件调度、I/O复用、网络编程接口等,帮助开发者快速构建可移植的应用...

    C++网络编程 卷2 基于ACE和框架的系统化复用

    《C++网络编程 卷2 基于ACE和框架的系统化复用》是一本深入探讨C++网络编程的专业书籍,主要关注如何利用ACE(Adaptive Communication Environment)框架进行高效、可复用的系统开发。ACE是一个强大的、跨平台的C++...

    ACE学习文档大全.rar

    ACE(Adaptive Communication Environment)是一个跨平台的C++网络编程框架,它提供了高效、可靠且灵活的网络通信解决方案。这个“ACE学习文档大全.rar”压缩包文件包含了丰富的资源,可以帮助初学者快速入门并深入...

    ACE并发编程示例及Task类的实现

    本主题主要围绕"ACE并发编程示例及Task类的实现"展开,我们将深入探讨并发编程的概念以及如何利用ACE框架中的ACE_Task类来实现并发任务。 并发编程是让多个任务或进程在一段时间内交替执行,从而提高系统资源利用率...

    tpd_reactor_proactor.pdf

    * 网络服务器:Reactor 和 Proactor 模式可以用于设计高效的网络服务器,处理大量的网络请求。 * 网络客户端:Reactor 和 Proactor 模式可以用于设计高效的网络客户端,处理网络请求和响应。 * 分布式系统:Reactor ...

    C++ Network Programming, Volume 2: Systematic Reuse with ACE and Frameworks

    对于期望深入学习和掌握C++网络编程的开发者来说,本书提供了一套完善的理论体系和实践指南,通过学习ACE框架的应用,可以有效提升网络编程的技能,并且能够掌握如何在复杂的网络和分布式系统中实现高效的代码重用。...

    ACE.rar_ACE 网络 编程_visual c

    这个RAR压缩包中的资源,"ACE.chm",是一部关于ACE网络编程的开发说明文档,特别适合初学者入门学习。通过这份文档,你可以深入理解ACE的核心概念和技术,并学会如何在Visual C++环境下进行实际的网络编程。 一、...

    ACE框架详细讲解,包括ACE框架详解、用户指南、案例分析

    ACE框架包含了许多核心组件,如Acceptor-Connector设计模式、Reactor模式、Proactor模式,这些都是实现异步事件驱动编程的关键元素。 "用户指南"将引导你如何有效地使用ACE框架。它通常会涵盖安装步骤、配置环境、...

Global site tag (gtag.js) - Google Analytics