采用 ACE Reactor 实现服务程序例子

前端之家收集整理的这篇文章主要介绍了采用 ACE Reactor 实现服务程序例子前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

此文版权属于作者所有,任何人、媒体或者网站转载、借用都必须征得作者本人同意!@H_404_2@

ACE 使用方法及例子,网上有不少,下面贴一段我写的采用 ACE Reactor 模式写的 echo 服务的例子代码,通过例子可以看出,采用 ACE 开发多客户端的服务程序那是相当简单的!@H_404_2@

代码中,handle_input(@H_404_2@…@H_404_2@)@H_404_2@和 handle_output(@H_404_2@…@H_404_2@)@H_404_2@都会对 _bufs @H_404_2@进行操作,因为这两个函数都是运行在 reactor 的线程里,不会冲突,所以没有必要对 _bufs 的操作进行锁操作。

/* $Id: cpp.tpl 3412 2009-11-14 14:23:44Z luozhiyong $ */@H_404_2@
/**@H_404_2@
* \file ACEReactorSvrSample.cpp@H_404_2@
*@H_404_2@
* \brief @H_404_2@ 采用ACE Reactor 实现服务程序例子@H_404_2@
*@H_404_2@
* \version $Rev: 3412 $@H_404_2@
* \author@H_404_2@
* \date 2009@H_404_2@ 年09月08日08:17:10@H_404_2@
*@H_404_2@
* \note @H_404_2@ 修改历史:<br>@H_404_2@
* <table>@H_404_2@
* <tr><th>@H_404_2@ 日期</th><th>修改人</th><th>内容</th></tr>@H_404_2@
* <tr><td>2009-9-8</td><td>@H_404_2@ </td><td>创建初稿</td>@H_404_2@
* </tr>@H_404_2@
* </table>@H_404_2@
*/@H_404_2@
#include@H_404_2@ <ace/Message_Block.h>@H_404_2@
#include@H_404_2@ <ace/Svc_Handler.h>@H_404_2@
#include@H_404_2@ <ace/SOCK_Acceptor.h>@H_404_2@
#include@H_404_2@ <ace/Acceptor.h>@H_404_2@
#include@H_404_2@ <ace/Select_Reactor.h>@H_404_2@
#include@H_404_2@ <list>@H_404_2@
#include@H_404_2@ <string>@H_404_2@
@H_404_2@
#ifdef@H_404_2@ _DEBUG@H_404_2@
# define@H_404_2@ ACE_RT_OPT@H_404_2@ "d"@H_404_2@
#else@H_404_2@
# define ACE_RT_OPT@H_404_2@
#endif@H_404_2@
@H_404_2@
#if@H_404_2@ defined@H_404_2@ _DLL@H_404_2@
# define@H_404_2@ ACE_LIB_THREAD_OPT@H_404_2@
#else@H_404_2@
# define ACE_LIB_THREAD_OPT "s"@H_404_2@
#endif@H_404_2@
@H_404_2@
#pragma@H_404_2@ comment@H_404_2@( lib@H_404_2@,"ACE"@H_404_2@ ACE_LIB_THREAD_OPT@H_404_2@ ACE_RT_OPT@H_404_2@ ".lib"@H_404_2@)
class@H_404_2@ EchoService@H_404_2@
: public@H_404_2@ ACE_Event_Handler@H_404_2@
{
public@H_404_2@:
typedef@H_404_2@ ACE_SOCK_STREAM@H_404_2@ stream_type@H_404_2@;
typedef@H_404_2@ EchoService@H_404_2@ my_type@H_404_2@;
typedef@H_404_2@ ACE_Acceptor@H_404_2@< my_type@H_404_2@, ACE_SOCK_ACCEPTOR@H_404_2@> acceptor_type@H_404_2@;
EchoService@H_404_2@()
{
printf@H_404_2@( "EchoService@H_404_2@ 创建\n"@H_404_2@);
}
~ EchoService@H_404_2@()
{
printf@H_404_2@( "EchoService@H_404_2@ 销毁\n"@H_404_2@);
}
// @H_404_2@ 响应socket 已经打开,连接已经建立事件@H_404_2@
int@H_404_2@ open@H_404_2@( void@H_404_2@*)
{
// @H_404_2@ 注册读事件@H_404_2@
if@H_404_2@ ( reactor@H_404_2@()-> register_handler@H_404_2@( this@H_404_2@,ACE_Event_Handler@H_404_2@:: READ_MASK@H_404_2@))
{
// @H_404_2@ 无法注册handler@H_404_2@
return@H_404_2@ -1;
}
// @H_404_2@ 注册写事件@H_404_2@
if@H_404_2@ ( reactor@H_404_2@()-> register_handler@H_404_2@( this@H_404_2@,ACE_Event_Handler@H_404_2@:: WRITE_MASK@H_404_2@))
{
// @H_404_2@ 无法注册handler@H_404_2@
return@H_404_2@ -1;
}
// @H_404_2@ 取消写事件,等待有数据时唤醒@H_404_2@
reactor@H_404_2@()-> cancel_wakeup@H_404_2@( this@H_404_2@,ACE_Event_Handler@H_404_2@:: WRITE_MASK@H_404_2@);
printf@H_404_2@( "EchoService@H_404_2@ 已打开\n"@H_404_2@);
return@H_404_2@ 0;
}
// @H_404_2@ 响应有数据可读事件@H_404_2@
int@H_404_2@ handle_input@H_404_2@( ACE_HANDLE@H_404_2@)
{
char@H_404_2@ buf@H_404_2@[24];
ssize_t@H_404_2@ c@H_404_2@ = _peer@H_404_2@. recv@H_404_2@( buf@H_404_2@,sizeof@H_404_2@( buf@H_404_2@) - 1);
if@H_404_2@ ( c@H_404_2@ == 0)
{
// @H_404_2@ 连接已经关闭@H_404_2@
return@H_404_2@ -1;
}
_bufs@H_404_2@. push_back@H_404_2@( std@H_404_2@:: string@H_404_2@( buf@H_404_2@,c@H_404_2@));
if@H_404_2@ ( _bufs@H_404_2@. size@H_404_2@() == 1)
{
// @H_404_2@ 缓冲区尺寸为1 说明原来缓冲区为空,写事件是取消的,这里唤醒它@H_404_2@
reactor@H_404_2@()-> schedule_wakeup@H_404_2@( this@H_404_2@,ACE_Event_Handler@H_404_2@:: WRITE_MASK@H_404_2@);
}
return@H_404_2@ 0;
}
// @H_404_2@ 响应可以发送数据了事件@H_404_2@
int@H_404_2@ handle_output@H_404_2@( ACE_HANDLE@H_404_2@)
{
while@H_404_2@ (! _bufs@H_404_2@. empty@H_404_2@())
{
std@H_404_2@:: string@H_404_2@& buf@H_404_2@(* _bufs@H_404_2@. begin@H_404_2@());
char@H_404_2@ const@H_404_2@* s@H_404_2@( buf@H_404_2@. c_str@H_404_2@());
char@H_404_2@ const@H_404_2@* const@H_404_2@ e@H_404_2@( s@H_404_2@ + buf@H_404_2@. size@H_404_2@());
while@H_404_2@ ( s@H_404_2@ != e@H_404_2@)
{
ssize_t@H_404_2@ c@H_404_2@( _peer@H_404_2@. send@H_404_2@( s@H_404_2@,e@H_404_2@ - s@H_404_2@));
if@H_404_2@ ( c@H_404_2@ == -1 || c@H_404_2@ == 0)
{
// @H_404_2@ 发送不成功不论发送过程中是否发生阻塞,@H_404_2@
if@H_404_2@ ( ACE_OS@H_404_2@:: last_error@H_404_2@() == EWOULDBLOCK@H_404_2@)
{
// @H_404_2@ 输出缓冲区满,无法再发送数据了(如果你还是继续发送数据,发送会阻塞的)@H_404_2@
break@H_404_2@;
} else@H_404_2@{
// @H_404_2@ 连接已关闭@H_404_2@
break@H_404_2@;
}
} else@H_404_2@{
s@H_404_2@ += c@H_404_2@;
}
}
if@H_404_2@ ( s@H_404_2@ == e@H_404_2@)
{
_bufs@H_404_2@. pop_front@H_404_2@();
} else@H_404_2@{
buf@H_404_2@ = std@H_404_2@:: string@H_404_2@( s@H_404_2@,e@H_404_2@ - s@H_404_2@);
break@H_404_2@;
}
}
if@H_404_2@ ( _bufs@H_404_2@. empty@H_404_2@())
{
// @H_404_2@ 缓冲区为空,取消写事件监听@H_404_2@
reactor@H_404_2@()-> cancel_wakeup@H_404_2@( this@H_404_2@,ACE_Event_Handler@H_404_2@:: WRITE_MASK@H_404_2@);
}
// @H_404_2@ 不论发送是否成功都返回0,因为,如果发送失败,handle_input 也会发生读失败事件,@H_404_2@
// @H_404_2@ 错误处理有handle_input 返回-1 来触发@H_404_2@
return@H_404_2@ 0;
}
int@H_404_2@ handle_close@H_404_2@( ACE_HANDLE@H_404_2@ = ACE_INVALID_HANDLE@H_404_2@,ACE_Reactor_Mask@H_404_2@ mask@H_404_2@ = ACE_Event_Handler@H_404_2@:: ALL_EVENTS_MASK@H_404_2@)
{
if@H_404_2@ ( mask@H_404_2@ == ACE_Event_Handler@H_404_2@:: WRITE_MASK@H_404_2@)
return@H_404_2@ 0;
_peer@H_404_2@. close@H_404_2@();
delete@H_404_2@ this@H_404_2@;
return@H_404_2@ 0;
}
// @H_404_2@ 这个函数主要给reactor::register_handler 时使用的@H_404_2@
ACE_HANDLE@H_404_2@ get_handle@H_404_2@ () const@H_404_2@
{
return@H_404_2@ _peer@H_404_2@. get_handle@H_404_2@();
}
// @H_404_2@ 这个函数主要给acceptor 使用的@H_404_2@
stream_type@H_404_2@& peer@H_404_2@()
{
return@H_404_2@ _peer@H_404_2@;
}
// @H_404_2@ 这个函数主要给acceptor 使用的@H_404_2@
int@H_404_2@ close@H_404_2@ ( u_long@H_404_2@ = 0)
{
return@H_404_2@ handle_close@H_404_2@();
}
private@H_404_2@:
stream_type@H_404_2@ _peer@H_404_2@;
std@H_404_2@:: list@H_404_2@< std@H_404_2@:: string@H_404_2@> _bufs@H_404_2@;
};
int@H_404_2@ main@H_404_2@( int@H_404_2@ /*argc*/@H_404_2@,char@H_404_2@* /*argv*/@H_404_2@[])
{
u_short@H_404_2@ port@H_404_2@ = 20001;
ACE_Reactor@H_404_2@:: instance@H_404_2@( new@H_404_2@ ACE_Reactor@H_404_2@( new@H_404_2@ ACE_Select_Reactor@H_404_2@,true@H_404_2@));
EchoService@H_404_2@:: acceptor_type@H_404_2@ acceptor@H_404_2@;
ACE_INET_Addr@H_404_2@ svrAddr@H_404_2@( port@H_404_2@);
if@H_404_2@ ( acceptor@H_404_2@. open@H_404_2@( svrAddr@H_404_2@))
{
fprintf@H_404_2@( stderr@H_404_2@,"@H_404_2@ 服务打开失败:%s\n"@H_404_2@,ACE_OS@H_404_2@:: strerror@H_404_2@( ACE_OS@H_404_2@:: last_error@H_404_2@()));
return@H_404_2@ 1;
} else@H_404_2@{
fprintf@H_404_2@( stdout@H_404_2@,"@H_404_2@ 服务已打开,端口为:%u\n"@H_404_2@,port@H_404_2@);
ACE_Reactor@H_404_2@:: instance@H_404_2@()-> run_reactor_event_loop@H_404_2@();
return@H_404_2@ 0;
}
}

猜你在找的React相关文章