/*
* reactor_echo_server.cpp
#include <ace/Event_Handler.h>
#include <ace/SOCK_Stream.h>
#include <ace/SOCK_Acceptor.h>
#include <ace/Timer_Queue.h>
#include <ace/Reactor.h>
#include <ace/Log_Msg.h>
#include <ace/Singleton.h>
#include <ace/Dev_Poll_Reactor.h>
#include <string>
#include <map>
typedef int (*CmdHandler)(const std::string& param, ACE_SOCK_Stream& sock);
class CmdHandlers {
public:
bool registerCmdHandler(const std::string& cmd, CmdHandler h) {
handlers.insert(std::make_pair(cmd, h));
return true;
}
CmdHandler getCmdHandler(const std::string& cmd) {
std::map<std::string, CmdHandler>::iterator i = handlers.find(cmd);
return i != handlers.end() ? i->second : CmdHandler();
}
private:
std::map<std::string, CmdHandler> handlers;
};
typedef ACE_Singleton<CmdHandlers, ACE_Null_Mutex> CmdHandlerInst;
static const ACE_Time_Value MAX_INTERVAL(300);
class Connection: public ACE_Event_Handler {
public:
Connection() {
}
~Connection() {
ACE_DEBUG((LM_DEBUG, "~Connection()\n"));
}
int open(ACE_Reactor* react) {
const char* welcome = "220 Welcome.\r\n";
if (sock.send(welcome, ACE_OS::strlen(welcome)) == -1)
ACE_ERROR_RETURN((LM_ERROR, "%p\n", "sock.send()"), -1);
this->reactor(react);
if (reactor()->schedule_timer(this, 0, ACE_Time_Value::zero,
MAX_INTERVAL) == -1)
ACE_ERROR_RETURN((LM_ERROR, "%p\n", "reactor().schedule_timer()"),
-1);
lastMsgTime = reactor()->timer_queue()->gettimeofday();
return reactor()->register_handler(this, READ_MASK);
}
ACE_SOCK_Stream& socket() {
return sock;
}
virtual ACE_HANDLE get_handle() const {
return sock.get_handle();
}
virtual int handle_input(ACE_HANDLE fd) {
ssize_t len = sock.recv(buf, sizeof buf);
if (len <= 0) {
if (len != 0)
ACE_ERROR_RETURN((LM_ERROR, "%p\n", "sock.recv()"), -1);
}
lastMsgTime = reactor()->timer_queue()->gettimeofday();
char* pos = ACE_OS::strstr(buf, "\r\n");
if (pos)
*pos = '\0';
pos = ACE_OS::strchr(buf, ' ');
std::string cmd, param;
if (pos) {
cmd = std::string(buf, pos);
param = std::string(pos + 1);
} else
cmd = buf;
CmdHandler h = CmdHandlerInst::instance()->getCmdHandler(cmd);
if (h)
return h(param, sock);
else {
const char* reply = "500 FTP: command not recognized.\r\n";
if (sock.send_n(reply, ACE_OS::strlen(reply)) == -1)
ACE_ERROR_RETURN((LM_ERROR, "%p\n", "sock.send_n()"), -1);
}
// if (sock.send_n(buf, len) != len) {
// ACE_ERROR((LM_ERROR, "%p\n", "sock.send_n()"));
// return -1;
// }
return 0;
}
virtual int handle_timeout(const ACE_Time_Value ¤t_time,
const void *act) {
if (current_time - lastMsgTime > MAX_INTERVAL)
reactor()->remove_handler(this, READ_MASK);
return 0;
}
virtual int handle_close(ACE_HANDLE handle, ACE_Reactor_Mask close_mask) {
if (handle == ACE_INVALID_HANDLE)
return 0;
// ACE_Reactor_Mask m = ALL_EVENTS_MASK | DONT_CALL;
reactor()->cancel_timer(this);
// reactor()->remove_handler(this, m);
sock.close();
delete this;
return 0;
}
private:
ACE_SOCK_Stream sock;
char buf[512];
ACE_Time_Value lastMsgTime;
};
// ----------------------------------------------------------------------------
class Acceptor: public ACE_Event_Handler {
public:
Acceptor() {
}
~Acceptor() {
ACE_DEBUG((LM_DEBUG, "~Acceptor()\n"));
}
int open(ACE_Reactor* react, unsigned short port) {
this->reactor(react);
ACE_INET_Addr addr;
if (addr.set(port) == -1)
ACE_ERROR_RETURN((LM_ERROR, "%p\n", "addr.set()"), -1);
if (acceptor.open(addr, 1) == -1)
ACE_ERROR_RETURN((LM_ERROR, "%p\n", "acceptor.open()"), -1);
return reactor()->register_handler(this, ACCEPT_MASK);
}
virtual ACE_HANDLE get_handle() const {
return acceptor.get_handle();
}
virtual int handle_input(ACE_HANDLE fd) {
Connection* con = new Connection();
if (acceptor.accept(con->socket()) == -1) {
ACE_ERROR((LM_ERROR, "%p\n", "acceptor.accept()"));
delete con;
} else {
if (con->open(reactor()) == -1)
delete con;
}
return 0;
}
private:
ACE_SOCK_Acceptor acceptor;
};
int main() {
ACE_Reactor* r = new ACE_Reactor(new ACE_Dev_Poll_Reactor, true);
ACE_Reactor::instance(r);
Acceptor acceptor;
if (acceptor.open(ACE_Reactor::instance(), 9988) == -1)
return 1;
return ACE_Reactor::instance()->run_reactor_event_loop();
}
// ----------------------------------------------------------------------------
int handleCmdSYST(const std::string& param, ACE_SOCK_Stream& sock) {
static const char* reply = "215 UNIX Type: L8\r\n";
if (sock.send(reply, ACE_OS::strlen(reply)) == -1)
ACE_ERROR_RETURN((LM_ERROR, "%p\n", "sock.send()"), -1);
return 0;
}
bool a = CmdHandlerInst::instance()->registerCmdHandler("SYST", handleCmdSYST);
基于ACE reactor_echo_server实现
最新推荐文章于 2020-03-02 15:05:43 发布