前端之家收集整理的这篇文章主要介绍了
基于ACE reactor_echo_server实现,
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
- /*
- * 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,ACE_Time_Value::zero,MAX_INTERVAL) == -1)
- ACE_ERROR_RETURN((LM_ERROR,"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,"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,"sock.send_n()"),-1);
- }
-
- // if (sock.send_n(buf,len) != len) {
- // ACE_ERROR((LM_ERROR,"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,"addr.set()"),-1);
-
- if (acceptor.open(addr,1) == -1)
- ACE_ERROR_RETURN((LM_ERROR,"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,"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,-1);
-
- return 0;
- }
-
-
- bool a = CmdHandlerInst::instance()->registerCmdHandler("SYST",handleCmdSYST);