在服务器端使用Reactor框架
使用Reactor框架的服务器端结构如下:
服务器端注册两种事件处理器,ClientAcceptor和ClientService ,ClientService类负责和客户端的通信,每一个ClientService对象对应一个客户端的Socket连接。 ClientAcceptor专门负责被动接受客户端的连接,并创建ClientService对象。这样,在一个N个Socket连接的服务器程序中,将存在1个ClientAcceptor对象和N个ClientService对象。
整个服务器端流程如下:
#include@H_404_27@ <ace/OS.h>
@H_404_27@#include@H_404_27@ <ace/Reactor.h>
@H_404_27@#include@H_404_27@ <ace/SOCK_Connector.h>@H_404_27@
#include@H_404_27@ <ace/SOCK_Acceptor.h>@H_404_27@
#include@H_404_27@ <ace/Auto_Ptr.h>
@H_404_27@class@H_404_27@ ClientService : public@H_404_27@ ACE_Event_Handler
{
public@H_404_27@:
ACE_SOCK_Stream &peer (void@H_404_27@) { return@H_404_27@ this@H_404_27@->sock_; }
int@H_404_27@ open (void@H_404_27@)
{
//注册读就绪回调函数
@H_404_27@return@H_404_27@ this@H_404_27@->reactor ()->register_handler(this@H_404_27@,ACE_Event_Handler::READ_MASK);
}
virtual@H_404_27@ ACE_HANDLE get_handle (void@H_404_27@) const@H_404_27@ { return@H_404_27@ this@H_404_27@->sock_.get_handle (); }
virtual@H_404_27@ int@H_404_27@ handle_input (ACE_HANDLE fd )
{
//一个简单的EchoServer,将客户端的信息返回
@H_404_27@int@H_404_27@ rev = peer().recv(buf,100);
if@H_404_27@(rev<=0)
return@H_404_27@ -1;
peer().send(buf,rev);
return@H_404_27@ 0;
}
// 释放相应资源@H_404_27@
virtual@H_404_27@ int@H_404_27@ handle_close (ACE_HANDLE,ACE_Reactor_Mask mask)
{
if@H_404_27@ (mask == ACE_Event_Handler::WRITE_MASK)
return@H_404_27@ 0;
mask = ACE_Event_Handler::ALL_EVENTS_MASK |
ACE_Event_Handler::DONT_CALL;
this@H_404_27@->reactor ()->remove_handler (this@H_404_27@,mask);
this@H_404_27@->sock_.close ();
delete@H_404_27@ this@H_404_27@;//socket出错时,将自动删除该客户端,释放相应资源
@H_404_27@return@H_404_27@ 0;
}
protected@H_404_27@:
char@H_404_27@ buf[100];
ACE_SOCK_Stream sock_;
};
class@H_404_27@ ClientAcceptor : public@H_404_27@ ACE_Event_Handler
{
public@H_404_27@:
virtual@H_404_27@ ~ClientAcceptor (){this@H_404_27@->handle_close (ACE_INVALID_HANDLE,0);}
int@H_404_27@ open (const@H_404_27@ ACE_INET_Addr &listen_addr)
{
if@H_404_27@ (this@H_404_27@->acceptor_.open (listen_addr,1) == -1)
{
ACE_OS::printf("open port fail"@H_404_27@);
return@H_404_27@ -1;
}
//注册接受连接回调事件
@H_404_27@return@H_404_27@ this@H_404_27@->reactor ()->register_handler(this@H_404_27@,ACE_Event_Handler::ACCEPT_MASK);
}
virtual@H_404_27@ ACE_HANDLE get_handle (void@H_404_27@) const
@H_404_27@{ return@H_404_27@ this@H_404_27@->acceptor_.get_handle (); }
virtual@H_404_27@ int@H_404_27@ handle_input (ACE_HANDLE fd )
{
ClientService *client = new@H_404_27@ ClientService();
auto_ptr<ClientService> p (client);
if@H_404_27@ (this@H_404_27@->acceptor_.accept (client->peer ()) == -1)
{
ACE_OS::printf("accept client fail"@H_404_27@);
return@H_404_27@ -1;
}
p.release ();
client->reactor (this@H_404_27@->reactor ());
if@H_404_27@ (client->open () == -1)
client->handle_close (ACE_INVALID_HANDLE,0);
return@H_404_27@ 0;
}
@H_404_27@virtual@H_404_27@ int@H_404_27@ handle_close (ACE_HANDLE handle,
ACE_Reactor_Mask close_mask)
{
if@H_404_27@ (this@H_404_27@->acceptor_.get_handle () != ACE_INVALID_HANDLE)
{
ACE_Reactor_Mask m = ACE_Event_Handler::ACCEPT_MASK |
ACE_Event_Handler::DONT_CALL;
this@H_404_27@->reactor ()->remove_handler (this@H_404_27@,m);
this@H_404_27@->acceptor_.close ();
}
return@H_404_27@ 0;
}
protected@H_404_27@:
ACE_SOCK_Acceptor acceptor_;
};
int@H_404_27@ main(int@H_404_27@ argc,char@H_404_27@ *argv[])
{
ACE_INET_Addr addr(3000,"192.168.1.142"@H_404_27@);
ClientAcceptor server;
server.reactor(ACE_Reactor::instance());
server.open(addr);
while@H_404_27@(true@H_404_27@)
{
ACE_Reactor::instance()->handle_events();
}
return@H_404_27@ 0;
}@H_404_27@ @H_404_27@