ACE Reactor模型学习

ACE Reactor框架可以用事件驱动的方式来处理网络化的操作,也可以用来处理信号和实现定时器的功能.在非Windows平台上,其默认用select模型实现(实现类为:ACE_Select_Reactor);在Windows平台上利用WSAEventSelect模型实现(实现类为:ACE_WFMO_Reactor). 其主要角色包括:

ACE_Reactor:在Reactor框架中管理事件处理器,执行其事件循环来驱动事件检测、多路分离等功能.

ACE_Event_Handler:ACE_Reactor回调的目标,其定义了各种挂钩方法以供ACE_Reactor回调处理.

示例:

/*
*  网络数据读取发送操作的封装
*/
class   CClientSocketHandler :  public  ACE_Event_Handler
{
private :
    ACE_SOCK_Stream   m_stream;                          
// 流对象
    ACE_TCHAR  m_szName[MAXHOSTNAMELEN];     // 保存连接上的主机名

public :
    ACE_SOCK_Stream
&   Peer()
    {
        
return   this -> m_stream;
    }

    
virtual  ACE_HANDLE get_handle ( void const
    {
        
return   this -> m_stream.get_handle();
    }

    
int   Init( )
    {
        ACE_INET_Addr  addrRemote;
        
if this -> m_stream.get_remote_addr( addrRemote )  ==   0  )   // 获取连接的远程地址
        {
            
if ( addrRemote.addr_to_string( m_szName,  sizeof ( ACE_TCHAR)  *  _countof( m_szName ) )  ==   0  )
            {
                ACE_DEBUG(( LM_DEBUG, ACE_TEXT(
" %s connected!\n " ), m_szName ));
            }
        }
        
// 向反应器登记,这里只登记为读操作以求简便
         return    this -> reactor() -> register_handler(  this , ACE_Event_Handler::READ_MASK );
    }

    
virtual   int  handle_input ( ACE_HANDLE )
    {
        
// 此时在网络连接上有数据可以读取
         char  szBuffer[ 4096 ];
        ssize_t  nRecv 
=   0 ;
        nRecv  
=    this -> m_stream.recv( szBuffer, _countof(szBuffer) );
        
if ( nRecv  <=   0  )
        {
            ACE_DEBUG(( LM_DEBUG, ACE_TEXT(
" %s connection closed\n " ), m_szName ));
            
return   - 1 ;
        }

        szBuffer[nRecv] 
=   ' \0 ' ;
        
// 显示读取数据
        ACE_DEBUG(( LM_DEBUG, ACE_TEXT( " recv from:%s   msg:%s\n " ), m_szName, ACE_TEXT_CHAR_TO_TCHAR(szBuffer) ));

        
return   0 ;
    }

    
virtual   int  handle_close ( ACE_HANDLE handle,     ACE_Reactor_Mask close_mask )
    {
        
// 指定DONT_CALL,表示解除登记时不需要调用该事件处理器的handle_close方法
        ACE_Reactor_Mask  mask  =   ACE_Event_Handler::READ_MASK  |  ACE_Event_Handler::DONT_CALL;
        
this -> reactor() -> remove_handler(  this , mask );    // 解除登记
         this -> m_stream.close();   // 关闭流对象
        delete  this ;    // 销毁自己
         return   0 ;
    }
};


/*
* 接受连接处理类
*/
class   CClientSocketAccept :  public  ACE_Event_Handler
{
private :
    ACE_SOCK_Acceptor  m_acceptor;

public :
    
virtual   ~ CClientSocketAccept()
    {
        
this -> handle_close( ACE_INVALID_HANDLE,  0  );
    }

    
int   Init(  const  ACE_INET_Addr &  addr )
    {
        
if this -> m_acceptor.open( addr,  1  )  ==   - 1  )
        {
            
int  n  =  errno;
            ACE_ERROR_RETURN(( LM_ERROR, ACE_TEXT(
" ACE_SOCK_Acceptor.open() Failed " )),  - 1  );
        }
        
return   this -> reactor() -> register_handler(  this , ACE_Event_Handler::ACCEPT_MASK );
    }

    
virtual  ACE_HANDLE get_handle ( void const
    {
        
return  m_acceptor.get_handle();
    }

    
virtual   int  handle_input ( ACE_HANDLE handle  =  ACE_INVALID_HANDLE )
    {
        
// 有新的连接来到了
        CClientSocketHandler   * pSockHandler   =   NULL;
        ACE_NEW_RETURN( pSockHandler, CClientSocketHandler, 
- 1  );

        
if this -> m_acceptor.accept( pSockHandler -> Peer() )  ==   - 1  )
        {
            delete pSockHandler;
            ACE_ERROR_RETURN(( LM_ERROR, ACE_TEXT(
" ACE_SOCK_Acceptor.accept() Failed " )),  - 1  );
        }

        pSockHandler
-> reactor(  this -> reactor() );
        
if ( pSockHandler -> Init()  ==   - 1  )
        {
            pSockHandler
-> handle_close( ACE_INVALID_HANDLE,  0  );
        }

        
return   0 ;
    }

    
virtual   int  handle_close ( ACE_HANDLE ,     ACE_Reactor_Mask )
    {
        
if  (  this -> m_acceptor.get_handle()  !=  ACE_INVALID_HANDLE )
        {
            ACE_Reactor_Mask  mask 
=   ACE_Event_Handler::ACCEPT_MASK  |  ACE_Event_Handler::DONT_CALL;
            
this -> reactor() -> remove_handler(  this , mask );
            
this -> m_acceptor.close();
        }
        
return   0 ;
    }
};
// /
     // 监听9981端口,循环处理客户端连接
    ACE_INET_Addr  addr(  9981  );   // 监听9981端口

    ACE_Reactor
*  pReactor  =   ACE_Reactor::instance();

    CClientSocketAccept  acceptor;
    acceptor.reactor( pReactor );

    
if ( acceptor.Init( addr )  ==   - 1  )
    {
        
return   - 1 ;
    }

    pReactor
-> run_reactor_event_loop();

 

转载于:https://www.cnblogs.com/fangkm/archive/2009/07/18/1526196.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值