ACE反应器模式:ACE_Reactor
来源:互联网 发布:php 文件上传代码 编辑:程序博客网 时间:2024/04/28 09:39
在服务器socket编程中,用来处理客户端的请求,最直接的做法是,为每一个socket连接创建一个线程,采用阻塞模式的方法来处理,然这种阻塞模式随着并发量增大,效果也会越来越差。一种比较好的方法就是select模型的思想。比如可把来自客户端的连接保存在一个cook中,采用轮询的方式检测某个连接是否可读或者可写。ACE反应器模式与这种思想类似。
ACE_Reactor的使用很简单,在服务端可以注册两个事件,一个用来处理客户端的连接,这种是被动接受客户端的请求,这里称作ClientAcceptor,当接受到客户端请求时,注册一个事件用来专门负责和客户端通信,这里称作ClientService。这样在有N个连接的服务器就会出现一个ClientAcceptor对象和N个ClientService对象,当某一个客户端连接断开则删除cook中的记录,并析构掉一个ClientService对象。
以下是服务器一个实例:
头文件需要包括:
#include<ace/OS.h>#include<ace/Reactor.h>#include<ace/SOCK_Connector.h>#include<ace/SOCK_Acceptor.h>#include<ace/Auto_Ptr.h>ClientAcceptor:专门负责处理来自客户端的连接
class ClientAcceptor : public ACE_Event_Handler{public: virtual ~ClientAcceptor (){this->handle_close (ACE_INVALID_HANDLE, 0);} int open (const ACE_INET_Addr &listen_addr) { if (this->acceptor_.open (listen_addr, 1) == -1) { ACE_OS::printf("open port fail"); return -1; } //注册接受连接回调事件 returnthis->reactor ()->register_handler(this, ACE_Event_Handler::ACCEPT_MASK); } virtual ACE_HANDLE get_handle (void) const { returnthis->acceptor_.get_handle (); } virtualint handle_input (ACE_HANDLE fd ) { ClientService *client = new ClientService(); auto_ptr<ClientService> p (client); if (this->acceptor_.accept (client->peer ()) == -1) { ACE_OS::printf("accept client fail"); return -1; } p.release (); client->reactor (this->reactor ()); if (client->open () == -1) client->handle_close (ACE_INVALID_HANDLE, 0); return 0; } virtualint handle_close (ACE_HANDLE handle, ACE_Reactor_Mask close_mask) { if (this->acceptor_.get_handle () != ACE_INVALID_HANDLE) { ACE_Reactor_Mask m = ACE_Event_Handler::ACCEPT_MASK | ACE_Event_Handler::DONT_CALL; this->reactor ()->remove_handler (this, m); this->acceptor_.close (); } return 0; }protected: ACE_SOCK_Acceptor acceptor_;};
ClientService:负责和客户端通信
class ClientService : public ACE_Event_Handler{public: ACE_SOCK_Stream &peer (void) { returnthis->sock_; } int open (void) { //注册读就绪回调函数 returnthis->reactor ()->register_handler(this, ACE_Event_Handler::READ_MASK); } virtual ACE_HANDLE get_handle (void) const { returnthis->sock_.get_handle (); } virtualint handle_input (ACE_HANDLE fd ) { //一个简单的EchoServer,将客户端的信息返回 int rev = peer().recv(buf,100); if(rev<=0) return -1; peer().send(buf,rev); return 0; } // 释放相应资源virtualint handle_close (ACE_HANDLE, ACE_Reactor_Mask mask) { if (mask == ACE_Event_Handler::WRITE_MASK) return 0; mask = ACE_Event_Handler::ALL_EVENTS_MASK | ACE_Event_Handler::DONT_CALL; this->reactor ()->remove_handler (this, mask); this->sock_.close (); deletethis; //socket出错时,将自动删除该客户端,释放相应资源 return 0; }protected: char buf[100]; ACE_SOCK_Stream sock_;};
main函数就更简单了:
int main(int argc, char *argv[]) { ACE_INET_Addr addr(3000,"192.168.1.142"); ClientAcceptor server; server.reactor(ACE_Reactor::instance()); server.open(addr); while(true) { ACE_Reactor::instance()->handle_events(); } return 0; }实际上ACE反应器的功能还很强大,实现了多事件分离机制,将不同的事件类型交给不同的事件处理器,通过框架内部一张表来维护。
0 0
- ACE反应器模式:ACE_Reactor
- ACE反应器(Reactor)模式
- ACE反应器(Reactor)模式
- ACE反应器(Reactor)模式
- ACE反应器(Reactor)模式
- ACE反应器(Reactor)模式
- ACE反应器(Reactor)模式
- ACE反应器(Reactor)模式
- ACE反应器(Reactor)模式
- ACE反应器(Reactor)模式
- ACE反应器(Reactor)模式
- ACE反应器(Reactor)模式
- ACE反应器(Reactor)模式
- ACE反应器(Reactor)模式
- ACE反应器(Reactor)模式(1)
- ACE反应器(Reactor)模式(1)
- ACE反应器(Reactor)模式(2)
- ACE反应器(Reactor)模式(3)
- Hadoop读书笔记——基础知识
- hunnu11327(凸包,凸包边界上所有的点都看作是多边形的端点)
- kvm简介(一)
- AE二次开发中,AxMapControl中地图复制到AxPageLayout控件中的代码
- POJ1003
- ACE反应器模式:ACE_Reactor
- 智慧城市,如此令人心驰神往
- 内核级驱动对抗Hook ZwSetInformationFile反删除技术
- PHP与MYSQL搭配出现中文乱码的“终极”解决方案
- MongoDB主从复制
- 单词拼接
- VMware ESX与VMware ESXi区别
- ZOJ3787:Access System
- 经典的NIM-poj-2975-Nim