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 (voidconst
    {
        
return this->m_stream.get_handle();
    }

    
int  Init( )
    {
        ACE_INET_Addr  addrRemote;
        
ifthis->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 )
    {
        
ifthis->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 (voidconst
    {
        
return m_acceptor.get_handle();
    }

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

        
ifthis->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();

 

posted @ 2009-07-18 16:21  孤竹君  阅读(1600)  评论(0编辑  收藏  举报