ACE_Reactor 反射机制 用 ACE_Reactor 实现SOCKET事件处理
所有需要事件处理的类须继承 ACE_Event_Handler 类,
并实现handle_signal方法,如果必要则要实现 get_handle 方法,表明事件触发对象是什么
当handle_signal方法返回-1时,会调用handle_close方法
通过 ACE_Reactor 的register_handler方法使事件处理对象同事件触发对象( ACE_Event )关联起来
register_handler方法有以下3种常用调用方式
1、 virtual int register_handler (ACE_Event_Handler *event_handler,
ACE_Reactor_Mask mask);
表为I/O事件注册事件通知
I/O事件触发的来源由 get_handle()方法提供
该方法会调用ACE_Event_Handler::add_reference()方法,如果当前事件注册通知没有被注册
2、 virtual int register_handler (ACE_HANDLE io_handle,
ACE_Event_Handler *event_handler,
ACE_Reactor_Mask mask);
方法2同方法1类似,但无需提供 get_handle()方法
3、virtual int register_handler (ACE_Event_Handler *event_handler,
ACE_HANDLE event_handle = ACE_INVALID_HANDLE);
只能使用在WIN平台
(ACE_Event的handle()返回事件处理句柄ACE_HANDLE)
要使触发事件正常运行,要执行 ACE_Reactor 的事件处理方法 handle_events(time),
不加time参数,则不会出现超时退出现象,除非调用了了ACE_Reactor的close方法
还可以利用ACE_Reactor的
resume_handler
suspend_handler
方法挂起和恢复事件通知
当然也可以使用remove_handler彻底删除事件通知
下面通过实例(来自ACE自带的例子,稍有改动)讲解如何利用ACE事件机制处理SOCKET I/O请求实现一个简单的SOCKET SERVER
涉及到以下主要系统类
ACE_INET_Addr :
网络地址类
其有多个构造函数,常见构造如下:
ACE_INET_Addr (u_short port_number,ACE_UINT32 ip_addr = INADDR_ANY);
ACE_INET_Addr (u_short port_number,const char host_name[],int address_family = AF_UNSPEC);
ACE_EXPLICIT ACE_INET_Addr (const char address[]);
ACE_SOCK_Acceptor
SOCKET接收器类,常用构造:
ACE_SOCK_Acceptor (const ACE_Addr &local_sap,
int reuse_addr = 0,
int protocol_family = PF_UNSPEC,
int backlog = ACE_DEFAULT_BACKLOG,
int protocol = 0);
参数reuse_addr =1表地址重用
其主要有如下方法:
open 方法
accept 方法
ACE_SOCK_Stream
SOCKET流处理类,该类可由ACE_SOCK_Acceptor的accept方法赋予实在的内容
提供有recv 、send、close等方法
ACE_Event_Handler
事件处理类
提供了一些事件触发时回调的一些方法的定义
基本实现思路:
在连接上设置事件触发机制和在接收后的数据读入上设置事件触发机制
源码如下:
#include "ace/Reactor.h"
#include "ace/WFMO_Reactor.h"
#include "ace/INET_Addr.h"
#include "ace/SOCK_Stream.h"
#include "ace/SOCK_Acceptor.h"
#include "ace/OS_main.h"
ACE_RCSID(WFMO_Reactor, Network_Events, "Network_Events.cpp,v 4.3 2003/11/05 09:36:08 jwillemsen Exp")
//数据读入时的事件处理类
class Network_Handler : public ACE_Event_Handler
{
public:
virtual int handle_input (ACE_HANDLE handle);
virtual int handle_close (ACE_HANDLE handle,
ACE_Reactor_Mask close_mask);
virtual ACE_HANDLE get_handle (void) const;
//数据读入时的事件触发对象
ACE_SOCK_Stream stream_;
};
ACE_HANDLE
Network_Handler::get_handle (void) const
{
return this->stream_.get_handle ();
}
int
Network_Handler::handle_input (ACE_HANDLE handle)
{
ACE_DEBUG ((LM_DEBUG, "Network_Handler::handle_input handle = %d/n", handle));
while (1)
{
char message[BUFSIZ];
int result = this->stream_.recv (message, sizeof message);
if (result > 0)
{
message[result] = 0;
ACE_DEBUG ((LM_DEBUG, "Remote message: %s/n", message));
}
else if (result == 0)
{
ACE_DEBUG ((LM_DEBUG, "Connection closed/n"));
//注意,要返回-1,以便handle_close执行
return -1;
}
else if (errno == EWOULDBLOCK)
{
return 0;
}
else
{
ACE_DEBUG ((LM_DEBUG, "Problems in receiving data, result = %d", result));
return -1;
}
}
}
int
Network_Handler::handle_close (ACE_HANDLE handle,
ACE_Reactor_Mask)
{
ACE_DEBUG ((LM_DEBUG, "Network_Handler::handle_close handle = %d/n", handle));
//注意:一定要调用close方法,不然你会发现在连接了4000个以上客户的时候,程序会变的越来越慢的
this->stream_.close ();
return 0;
}
//客户连接时的事件处理类
class Network_Listener : public ACE_Event_Handler
{
public:
Network_Listener (void);
// Default constructor
~Network_Listener (void);
// Default constructor
virtual int handle_input (ACE_HANDLE handle);
virtual int handle_close (ACE_HANDLE handle,
ACE_Reactor_Mask close_mask);
ACE_HANDLE get_handle (void) const;
ACE_INET_Addr local_address_;
//客户连接时的事件触发对象
ACE_SOCK_Acceptor acceptor_;
Network_Handler *handler;
};
Network_Listener::Network_Listener (void)
: local_address_ (ACE_DEFAULT_SERVER_PORT),
acceptor_ (local_address_, 1)
{
this->reactor (ACE_Reactor::instance ());
//向reactor注册连接事件
int result = this->reactor ()->register_handler (this,ACE_Event_Handler::ACCEPT_MASK);
ACE_ASSERT (result == 0);
handler=new Network_Handler();
}
Network_Listener::~Network_Listener (void)
{
}
ACE_HANDLE
Network_Listener::get_handle (void) const
{
return this->acceptor_.get_handle ();
}
int
Network_Listener::handle_input (ACE_HANDLE handle)
{
ACE_DEBUG ((LM_DEBUG, "Network_Listener::handle_input handle = %d/n", handle));
ACE_INET_Addr remote_address;
ACE_SOCK_Stream stream;
// 尝试重新关联事件
int reset_new_handle = this->reactor ()->uses_event_associations ();
int result = this->acceptor_.accept (stream, // stream
&remote_address, // 远端地址
0, // 超时设置
1, // 重用地址
reset_new_handle); // reset new handler
ACE_ASSERT (result == 0);
ACE_DEBUG ((LM_DEBUG, "Remote connection from: "));
remote_address.dump ();
handler->stream_=stream;
result = this->reactor ()->register_handler (handler,READ_MASK);
ACE_ASSERT (result == 0);
return 0;
}
int
Network_Listener::handle_close (ACE_HANDLE handle,
ACE_Reactor_Mask)
{
ACE_DEBUG ((LM_DEBUG, "Network_Listener::handle_close handle = %d/n", handle));
this->acceptor_.close ();
delete this;
return 0;
}
int
ACE_TMAIN (int, ACE_TCHAR *[])
{
Network_Listener *listener =
new Network_Listener;
//开始循环事件处理
ACE_Reactor::run_event_loop ();
return 0;
};