基于ACE reactor_echo_server实现
来源:互联网 发布:华为云 和阿里云哪个好 编辑:程序博客网 时间:2024/05/22 15:04
/* * 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);} elsecmd = 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);
0 0
- 基于ACE reactor_echo_server实现
- 基于ACE实现C++目录遍历
- 基于ACE的定时器队列实现
- 基于ACE Reacotr FTP server 简单实现
- 基于ACE实现的一个内存池-续篇
- 一个基于ACE的线程池的实现(转)
- 基于ACE的后台服务程序的实现
- 基于ACE中ACE_Event_Handler的定时器管理器实现
- 基于ACE网络编程配置
- C++实现的带最大最小线程数的线程池(基于ACE)
- C++实现的带最大最小线程数的线程池(基于ACE)
- 基于ACE的线程池学习与实现(一)——ACE_Task
- 基于ACE的线程池学习与实现(二)——ACE_Message_Block与ACE_Condition
- 基于ACE的线程池学习与实现(三)—— 并发编程资料
- ACE定时器代码实现
- 基于ACE应用编程框架——线程池 - [ACE]
- 基于ACE的网络服务端通讯编程
- 基于ACE的网络服务端通讯编程
- Oracle收集统计信息方法
- 线段树区间更新+poj2528
- Java线程池管理及分布式Hadoop调度框架搭建
- 非模态对话框 模态对话框 --创建和销毁过程
- Windows学习心得【模拟时钟】
- 基于ACE reactor_echo_server实现
- 排序算法之直接选择排序(内附交换两个数据交换的正确实现方法)
- 怎样搭建DB2 DPF(多分区) for Linux/Unix
- 关于fullcalendar里显示Ajax后台返回xml格式的events(1)
- [codility]TapeEquilibrium
- 物化视图
- 232电平和TTL电平
- VisualStudio 2010 SP1安装时提示计算机环境导致无法安装的解决办法 (非常感谢 http://hi.baidu.com/imtoby)
- UIKit Dynamics入门