Reactor,即反应堆。Reactor 的一般工作过程是首先在 Reactor 中注册(Reactor)感兴趣事件,并在注册时候指定个已定义的回调函数(callback);当客户端发送请求时,在 Reactor 中会触发刚才注册的事件,并调用对应的处理函数。在这一个处理回调函数中,一般会有数据接收、处理、回复请求等操作。将多个客户的请求分离和调度给应用程序。
- 应用启动,将关注的事件handle注册到Reactor中;
- 调用Reactor,进入无限事件循环,等待注册的事件到来;
- 事件到来,select返回,Reactor将事件分发到之前注册的回调函数中处理
2.1 服务端:
mReactor.h
#ifndef _MREACTOR_H_
#define _MREACTOR_H_
#include
#include
#include
#include
#include
#include
#include
#include "logger.h"//使用log4cplus
#include "strategy.h" //需要自己实现的方法类
/***
#include "common.h"
#include "strategy.h"
***/
//todo change MAX_BUF_LENGTH
#define MAX_BUF_LENGTH 1000
using namespace std;
class ClientService : public ACE_Event_Handler
{
public:
ClientService(ACE_SOCK_Stream new_stream,string cli_host,int cli_port)
:sock_(new_stream),
m_ip(cli_host),
m_port(cli_port)
{
}
ACE_SOCK_Stream& peer (void) { return this->sock_; }
void setStrategy(ProcStrategy* pStrategy) {m_pStrategy = pStrategy;}
int open (void)
{
//注册读就绪回调函数
return this->reactor ()->register_handler(this, ACE_Event_Handler::READ_MASK);
}
virtual ACE_HANDLE get_handle (void) const { return this->sock_.get_handle (); }
virtual int handle_input (ACE_HANDLE fd);
int sendRespond(string sendbuf);
// 释放相应资源
virtual int handle_close (ACE_HANDLE, ACE_Reactor_Mask mask);
protected:
char buf[MAX_BUF_LENGTH];
ACE_SOCK_Stream sock_;
ProcStrategy *m_pStrategy;
string m_ip;
int m_port;
};
class ClientAcceptor : public ACE_Event_Handler
{
public:
virtual ~ClientAcceptor(){this->handle_close (ACE_INVALID_HANDLE, 0);}
void setStrategy(ProcStrategy* pStrategy) {m_pStrategy = pStrategy;}
int open (const ACE_INET_Addr &listen_addr);
virtual ACE_HANDLE get_handle(void) const { return this->acceptor_.get_handle (); }
virtual int handle_input(ACE_HANDLE fd );
virtual int handle_close(ACE_HANDLE handle,ACE_Reactor_Mask close_mask);
protected:
ACE_SOCK_Acceptor acceptor_;
ACE_INET_Addr listen_addr_;
ProcStrategy *m_pStrategy; //需要自己实现的方法类 用于消息处理
};
#endif
mReactor.cpp
#include "mReactor.h"
int ClientService::sendRespond(string sendbuf)
{
int len = peer().send(sendbuf.c_str(),sendbuf.length());
LOG4CPLUS_INFO(g_logger, "send msg length:"<processReq(strReq,cmdType,getRsp);
//send response to client
string sendbuf;
m_pStrategy->processRsp(ret,cmdType,getRsp,sendbuf);
sendRespond(sendbuf);
return 0;
}
// 释放相应资源
int ClientService::handle_close(ACE_HANDLE, ACE_Reactor_Mask mask)
{
if (mask == ACE_Event_Handler::WRITE_MASK)
return 0;
LOG4CPLUS_INFO(g_logger, "client ip:"<reactor ()->remove_handler (this, mask);
this->sock_.close ();
delete this; //socket出错时,将自动删除该客户端,释放相应资源
return 0;
}
int ClientAcceptor::open (const ACE_INET_Addr &listen_addr)
{
listen_addr_ = listen_addr;
//if (this->acceptor_.open (listen_addr, 1) == -1)
if (this->acceptor_.open (listen_addr) == -1)
{
LOG4CPLUS_ERROR(g_logger, "open port fail,port:"<reactor ()->register_handler(this, ACE_Event_Handler::ACCEPT_MASK);
}
int ClientAcceptor::handle_input (ACE_HANDLE fd )
{
ACE_SOCK_Stream new_stream;
ACE_INET_Addr cli_addr;
string cli_host;
int cli_port = -1;
if (this->acceptor_.accept (new_stream,&cli_addr) == -1)
{
LOG4CPLUS_ERROR(g_logger, "accept client fail,client ip:"<setStrategy(m_pStrategy);
client->reactor (this->reactor ());
if (client->open () == -1)
{
LOG4CPLUS_ERROR(g_logger, "client open fail");
client->handle_close (ACE_INVALID_HANDLE, 0);
}
return 0;
}
int ClientAcceptor::handle_close (ACE_HANDLE handle,ACE_Reactor_Mask close_mask)
{
if (this->acceptor_.get_handle () != ACE_INVALID_HANDLE)
{
LOG4CPLUS_INFO(g_logger, "closing acceptor");
ACE_Reactor_Mask m = ACE_Event_Handler::ACCEPT_MASK |
ACE_Event_Handler::DONT_CALL;
this->reactor ()->remove_handler (this, m);
this->acceptor_.close ();
}
return 0;
}
main:
#include "mReactor.h"
#include "strategy.h"
int main()
{
//strategy
ProcStrategy *strategy = new Strategy();
strategy->setRedis(pRedis);
//ClientAcceptor
string t=m_ip+":"+m_port;
ACE_INET_Addr addr(t.c_str());
ClientAcceptor server;
server.setStrategy(strategy);
server.reactor(ACE_Reactor::instance());
LOG4CPLUS_INFO(g_logger, "listening addr:"<handle_events();
}
}
说明:懒,这是写好的代码里面kou出来的,想跑起来 还得改改
2.2 client端
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define TYPE32 int
#define TYPE64 long
#define PERNUMS 2000
void processReq()
{
}
void processRsp(string strresp)
{
}
void* func(void* start)
{
int startnum =(TYPE64)(start);
cout<
2.3代码使用方法:
linux下 ace安装使用
windows下http://blog.csdn.net/qq_34233232/article/details/52595211
参考现有的资料ctrl c v写出来的,算原创么