ACE反应器(Reactor)模式(3)
转载于:http://www.cnblogs.com/TianFang/archive/2006/12/18/595938.html
在服务器端使用Reactor框架
使用Reactor框架的服务器端结构如下:
服务器端注册两种事件处理器,ClientAcceptor和ClientService ,ClientService类负责和客户端的通信,每一个ClientService对象对应一个客户端的Socket连接。 ClientAcceptor专门负责被动接受客户端的连接,并创建ClientService对象。这样,在一个N个Socket连接的服务器程序中,将存在1个ClientAcceptor对象和N个ClientService对象。
整个服务器端流程如下:
- 首先创建一个ClientAcceptor对象,该对象在Reactor上注册ACCEPT_MASK事件,Reactor将自动在监听端口建立Socket监听。
- 如果有对该端口的Socket连接时,Reactor将自动回调handle_input方法,ClientAcceptor重载此方法,并创建一个ClientService对象,用于处理和Client的通信。
- ClientService对象根据服务器的具体功能实现,其处理过程和客户端程序类似,注册相应的回调事件并分发即可。
代码如下:
#include <ace/OS.h>
#include <ace/Reactor.h>
#include <ace/SOCK_Connector.h>
#include <ace/SOCK_Acceptor.h>
#include <ace/Auto_Ptr.h> class ClientService : public ACE_Event_Handler
{
public:
ACE_SOCK_Stream &peer (void) { return this->sock_; } int open (void)
{
//注册读就绪回调函数
return this->reactor ()->register_handler(this, ACE_Event_Handler::READ_MASK);
} virtual ACE_HANDLE get_handle (void) const { return this->sock_.get_handle (); } virtual int handle_input (ACE_HANDLE fd )
{
//一个简单的EchoServer,将客户端的信息返回
int rev = peer().recv(buf,);
if(rev<=)
return -; peer().send(buf,rev);
return ;
} // 释放相应资源
virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask mask)
{
if (mask == ACE_Event_Handler::WRITE_MASK)
return ;
mask = ACE_Event_Handler::ALL_EVENTS_MASK |
ACE_Event_Handler::DONT_CALL;
this->reactor ()->remove_handler (this, mask);
this->sock_.close ();
delete this; //socket出错时,将自动删除该客户端,释放相应资源
return ;
} protected:
char buf[];
ACE_SOCK_Stream sock_;
}; class ClientAcceptor : public ACE_Event_Handler
{
public:
virtual ~ClientAcceptor (){this->handle_close (ACE_INVALID_HANDLE, );} int open (const ACE_INET_Addr &listen_addr)
{
if (this->acceptor_.open (listen_addr, ) == -)
{
ACE_OS::printf("open port fail");
return -;
}
//注册接受连接回调事件
return this->reactor ()->register_handler(this, ACE_Event_Handler::ACCEPT_MASK);
} virtual ACE_HANDLE get_handle (void) const
{ return this->acceptor_.get_handle (); } virtual int handle_input (ACE_HANDLE fd )
{
ClientService *client = new ClientService();
auto_ptr<ClientService> p (client); if (this->acceptor_.accept (client->peer ()) == -)
{
ACE_OS::printf("accept client fail");
return -;
}
p.release ();
client->reactor (this->reactor ());
if (client->open () == -)
client->handle_close (ACE_INVALID_HANDLE, );
return ;
} virtual int 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 ;
} protected:
ACE_SOCK_Acceptor acceptor_;
}; int main(int argc, char *argv[])
{
ACE_INET_Addr addr(,"192.168.1.142");
ClientAcceptor server;
server.reactor(ACE_Reactor::instance());
server.open(addr); while(true)
{
ACE_Reactor::instance()->handle_events();
} return ;
}
代码功能比较简单,需要注意以下几点:
- 这里注册事件的方式和前面的文章中方式不一样,是通过ACE_Event_Handler类的reactor()方法设置和获取reactor的指针,比较直观和方便。前面的文章是通过ACE_Reactor::instance()来获取的一个单体reactor的指针。
- 当客户端Socket连接关闭时,需要释放相应资源,需要注意一下ClientService对象的handle_close方法中释放资源的相应代码。
ACE反应器(Reactor)模式(3)的更多相关文章
- ACE反应器(Reactor)模式(2)
转载于:http://www.cnblogs.com/TianFang/archive/2006/12/18/595808.html 在Socket编程中,常见的事件就是"读就绪" ...
- ACE反应器(Reactor)模式(1)
转载于:http://www.cnblogs.com/TianFang/archive/2006/12/13/591332.html 1.ACE反应器框架简介 反应器(Reactor):用于事件多路分 ...
- ACE反应器(Reactor)模式(4)
转载于:http://www.cnblogs.com/TianFang/archive/2006/12/18/596012.html 定时器的实现 通过Reactor机制,还可以很容易的实现定时器的功 ...
- 反应器(Reactor)模式
Java NIO非堵塞技术实际是采取反应器模式,或者说是观察者(observer)模式为我们监察I/O端口,如果有内容进来,会自动通知我们,这样,我们就不必开启多个线程死等,从外界看,实现了流畅的I/ ...
- ACE - Reactor模式源码剖析及具体实现(大量源码慎入)
原文出自http://www.cnblogs.com/binchen-china,禁止转载. 在之前的文章中提到过Reactor模式和Preactor模式,现在利用ACE的Reactor来实现一个基于 ...
- 什么是Reactor模式,或者叫反应器模式
Reactor这个词译成汉语还真没有什么合适的,很多地方叫反应器模式,但更多好像就直接叫reactor模式了,其实我觉着叫应答者模式更好理解一些.通过了解,这个模式更像一个侍卫,一直在等待你的召唤,或 ...
- Reactor模式,或者叫反应器模式
Reactor这个词译成汉语还真没有什么合适的,很多地方叫反应器模式,但更多好像就直接叫reactor模式了,其实我觉着叫应答者模式更好理解一些.通过了解,这个模式更像一个侍卫,一直在等待你的召唤,或 ...
- Reactor模式(反应器模式)
Reactor这个词译成汉语还真没有什么合适的,很多地方叫反应器模式,但更多好像就直接叫reactor模式了,其实我觉着叫应答者模式更好理解一些.通过了解,这个模式更像一个侍卫,一直在等待你的召唤,或 ...
- Reactor模式,或者叫反应器模式 - 为什么用多路io复用提供吞吐量
Reactor这个词译成汉语还真没有什么合适的,很多地方叫反应器模式,但更多好像就直接叫reactor模式了,其实我觉着叫应答者模式更好理解一些.通过了解,这个模式更像一个侍卫,一直在等待你的召唤,或 ...
随机推荐
- 查找 二叉树中 k1 到 k2区间的节点
vector<int> res; int key1, key2; void traverse(TreeNode * root){//采用前序遍历 if(root == NULL) retu ...
- UVa -1584 Circular Sequence 解题报告 - C语言
1.题目大意 输入长度为n$(2\le n\le 100)$的环状DNA串,找出该DNA串字典序最小的最小表示. 2.思路 这题特别简单,一一对比不同位置开始的字符串的字典序,更新result. 3. ...
- net::ERR_ABORTED ,引入js文件出现报错的解决方法
在head头里面添加 <mvc:annotation-driven enable-matrix-variables="true"></mvc:annotation ...
- Python运行的方式
Python的运行方式多种多样,下面列举几种: 交互式 在命令行中输入python,然后在>>>提示符后面输入Python语句,这里需要注意: 1 语句前面不能有空格,否则会报错 2 ...
- string && 字符数组
一.string 1. 使用字符串字面值初始化string对象 如:string s1 = "hiya"; string s2("hiya"); 该字面值的最后 ...
- 使用Quartz.Net同时执行多个任务
在Quartz.Net中可能我们需要在某一时刻执行多个任务操作,而又不想创建多个任务.Quartz.Net为我们提供了多个ScheduleJob的重载来实现多个一次执行多个任务. // 创建一个组任务 ...
- linux+Nginx+Mysql+PHP环境下,安装mysqli模块
奶奶的腿儿啊,太不易了.倒腾了小半天儿,写此随笔,待后查. 阿里云ecs中,安装phpcms,出现了一个问题:环境检测的时候,一直提示 Mysqli扩展没开启. 老夫哪儿特么会这么专业的啊...能咋办 ...
- 加密和数字签名工具GPG
转载: 源文件位置:http://blog.chinaunix.net/uid-9525959-id-2001824.html GPG [功能] GPG是加密和数字签名的免费工具,大多用于加密信息的 ...
- [C/C++] const用法详解
const在C语言中算是一个比较新的描述符,我们称之为常量修饰符,意即其所修饰的对象为常量(immutable). 我们来分情况看语法上它该如何被使用. 1.函数体内修饰局部变量.例:void fun ...
- SQL SERVER 存储过程中SELECT 返回值如何赋值给变量
今天在处理一个问题时,使用到一个存储过程,是用于更新并获取最新ID的.在使用过程中,需要获取到这个ID并赋值给变量,结果用EXEC @ID = 存储过程的方式获取失败了.具体情况如下: 为了还原整个情 ...