ACE Proactor模型示例
/*
* 异步处理套接字读取和发送操作
*/
class CClientSocketProactorHandler : public ACE_Service_Handler
{
private:
ACE_Asynch_Read_Stream m_readStream; //异步读取流
ACE_Asynch_Write_Stream m_writeStream; //异步写流
public:
~CClientSocketProactorHandler()
{
//关闭套接字
if( this->handle() != ACE_INVALID_HANDLE )
{
ACE_OS::closesocket( this->handle() );
}
}
//当有新的连接来到时,调用ACE_Service_Handler的open方法
virtual void open ( ACE_HANDLE new_handle, ACE_Message_Block &message_block )
{
//设置套接字
this->handle( new_handle );
//初始化读流和写流
if( ( this->m_readStream.open( *this, new_handle ) != 0 ) || ( this->m_writeStream.open( *this, new_handle ) != 0 ) )
{
ACE_DEBUG(( LM_DEBUG, ACE_TEXT("open aysnch failed!\n") ));
return;
}
//投送一个读取操作
ACE_Message_Block *mb;
ACE_NEW_NORETURN ( mb, ACE_Message_Block (1024) );
if ( this->m_readStream.read ( *mb, mb->space () ) != 0 )
{
ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Read Stream Failed\n") ));
mb->release ();
delete this;
return;
}
}
virtual void handle_read_stream (const ACE_Asynch_Read_Stream::Result &result)
{
ACE_Message_Block &mb = result.message_block();
if ( !result.success () || result.bytes_transferred () == 0 )
{ //套接字关闭
mb.release ();
ACE_DEBUG(( LM_DEBUG, ACE_TEXT("Socket Closed!\n") ));
delete this;
}
else
{
char szText[1024];
int nRecvLen = (int)mb.length();
memcpy( szText, mb.base(), nRecvLen);
szText[nRecvLen] = '\0';
ACE_DEBUG(( LM_DEBUG, ACE_TEXT("Recv text:%s!\n"), szText ));
//释放消息体
mb.release ();
//继续投送读取操作
ACE_Message_Block *new_mb;
ACE_NEW_NORETURN (new_mb, ACE_Message_Block (1024));
this->m_readStream.read (*new_mb, new_mb->space ());
}
}
virtual void handle_write_stream ( const ACE_Asynch_Write_Stream::Result &result )
{
result.message_block().release ();
}
};
/*
* 异步接受处理类
*/
class CClientSocketProactorAcceptor : public ACE_Asynch_Acceptor<CClientSocketProactorHandler>
{
public:
//挂钩操作,用于验证客户端的连接
virtual int validate_connection ( const ACE_Asynch_Accept::Result& result, const ACE_INET_Addr &remote, const ACE_INET_Addr& local )
{
ACE_TCHAR szName[MAXHOSTNAMELEN];
if( remote.addr_to_string( szName, sizeof( ACE_TCHAR) * _countof( szName ) ) == 0 )
{
ACE_DEBUG(( LM_DEBUG, ACE_TEXT("%s connected!\n"), szName ));
}
return 0;
}
};
使用:
//监听9981端口,循环处理客户端连接
ACE_INET_Addr addr( 9981 ); //监听9981端口
ACE_Proactor* pRroactor = ACE_Proactor::instance();
CClientSocketProactorAcceptor acceptor;
if( acceptor.open( addr, 0, 0, 5, 1, pRroactor, 1 ) != 0 )
{
ACE_DEBUG(( LM_DEBUG, ACE_TEXT(" Acceptor Open Failed!\n") ));
return -1;
}
pRroactor->proactor_run_event_loop();