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 ;
};
所有需要事件处理的类须继承 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 ;
};