ACE Reactor的Echo Server

简介:
相对完整的修改版本

  1  /* *********************************************************************** 
  2  * @file: echo.cpp                                                    
  3  * @author: dennis
  4  * @revise: dennis <killme2008@gmail.com>  http://www.blogjava.net/killme2008
  5  *          相对完整的echo server,可以接受多个客户端连接,并且可以通过键入quit正常关闭
  6 
  7  *********************************************************************** */
  8 
  9  #ifdef _DEBUG
 10  #pragma comment (lib, " aced.lib " )
 11  #else
 12  #pragma comment (lib, " ace.lib " )
 13  #endif
 14 
 15  #include  " ace/Reactor.h "
 16  #include  " ace/SOCK_Acceptor.h "
 17  #include  " ace/os.h "
 18  #include  " ace/Log_Msg.h "
 19  #include  " ace/inet_addr.h "
 20  #include  " ace/Thread_Manager.h "
 21  #include < iostream >
 22  #include < string >
 23 
 24  #define  PORT_NO 8080
 25  typedef ACE_SOCK_Acceptor Acceptor;
 26  // forward declaration
 27  class  Echo_Handler;
 28 
 29  class  Echo_Handler: public  ACE_Event_Handler
 30  {
 31  public :
 32       // construcor
 33      Echo_Handler()
 34      {
 35      }
 36       virtual   ~ Echo_Handler()
 37      {
 38      }
 39       // Called back to handle any input received
 40       int  handle_input(ACE_HANDLE)
 41      {
 42           // receive the data
 43          ssize_t recvBytes  =  peer().recv(data, 12 );
 44           if (recvBytes  <=   0 )
 45          {
 46              ACE_DEBUG((LM_DEBUG, " %s\n " , " 客户端断开连接 " ));
 47               return   - 1 ;
 48          }
 49          data[recvBytes]  =   0 ;
 50 
 51          ACE_DEBUG((LM_DEBUG, " %s\n " ,data));
 52 
 53 
 54           if (ACE_OS::strcmp(data, " q " ==   0 )
 55          {
 56              ACE_DEBUG((LM_DEBUG, " %s\n " , " 客户端退出 " ));
 57              peer().close();
 58               return   - 1 ;
 59          }
 60          peer().send_n(data,recvBytes);
 61           //  do something with the input received.
 62           //  
 63           //  keep yourself registerd with the reator
 64           return   0 ;
 65      }
 66 
 67       int  handle_close(ACE_HANDLE h,ACE_Reactor_Mask m)
 68      {
 69          delete  this ;
 70           return    0 ;
 71      }
 72 
 73       // Used by the reactor to determine the underlying handle
 74      ACE_HANDLE get_handle()   const  
 75      {
 76           return   this -> peer_.get_handle();
 77      }
 78 
 79       // Returns a reference to the underlying stream.
 80      ACE_SOCK_Stream &  peer()
 81      {
 82           return   this -> peer_;
 83      }
 84 
 85  private :
 86      ACE_SOCK_Stream peer_;
 87       char  data [ 12 ];
 88  };
 89 
 90  class  Echo_Accept_Handler: public  ACE_Event_Handler
 91  {
 92  public :
 93       // Constructor
 94      Echo_Accept_Handler(ACE_Addr  & addr)
 95      {
 96           this -> open(addr);
 97      }
 98       virtual   ~ Echo_Accept_Handler(){}
 99       // Open the peer_acceptor so it starts to "listen"
100       // for incoming clients
101       int  open(ACE_Addr  & addr)
102      {
103           if (peer_acceptor.open(addr) ==- 1 )
104              ACE_ERROR_RETURN((LM_ERROR, " 启动服务器错误\n " ), 1 );
105           return   0 ;
106      }
107 
108       // Overload the handle input method
109       int  handle_input(ACE_HANDLE handle)
110      {
111           // Client has requested connection to server.
112           // Create a handler to handle the connection
113          Echo_Handler  * eh;
114          ACE_NEW_RETURN(eh,Echo_Handler, - 1 );
115          ACE_INET_Addr cliaddr;
116           // Accept the connection "into" the Event Handler
117           if ( this -> peer_acceptor.accept(eh -> peer(), // stream
118               & cliaddr, // remote address
119               0 , // timeout
120               1 ==   - 1 ) // restart if interrupted
121              ACE_DEBUG((LM_ERROR, " Error in connection \n " ));
122 
123          ACE_DEBUG((LM_DEBUG, " 连接已经建立,来自%s\n " ,cliaddr.get_host_addr()));
124 
125           // Register the input event handler for reading 
126          ACE_Reactor::instance() -> register_handler(eh,ACE_Event_Handler::READ_MASK);
127           const   char *  msg  =   " 按q键使服务安全退出\r\n " ;
128          eh -> peer().send_n(msg,strlen(msg) + 1 );
129           return   0 ;
130      }
131 
132       // Used by the reactor to determine the underlying handle
133      ACE_HANDLE get_handle( void const
134      {
135           return   this -> peer_acceptor.get_handle();
136      }
137       int  handle_close(ACE_HANDLE h,ACE_Reactor_Mask m){
138          peer_acceptor.close();
139          delete  this ;
140           return   0 ;
141      }
142 
143  private :
144      Acceptor peer_acceptor;
145  };
146  class  Quit_Handler: public  ACE_Event_Handler
147  {
148  public :
149      Quit_Handler(ACE_Reactor *  r):ACE_Event_Handler(r){}
150       virtual   int  handle_exception(ACE_HANDLE)
151      {
152          ACE_DEBUG((LM_DEBUG, " 停止服务器中\n " ));
153          reactor() -> end_reactor_event_loop();
154           return   - 1 ;
155      }
156       int  handle_close(ACE_HANDLE h,ACE_Reactor_Mask m)
157      {
158          delete  this ;
159           return   0 ;
160      }
161       virtual   ~ Quit_Handler(){}
162  };
163  static  ACE_THR_FUNC_RETURN run_events ( void   * arg);
164  static  ACE_THR_FUNC_RETURN controller ( void   * arg);
165  int  ACE_TMAIN( int  argc, char   * argv[])
166  {
167 
168      ACE_Reactor *  reactor = ACE_Reactor::instance();
169       if (ACE_Thread_Manager::instance() -> spawn(run_events,reactor,THR_DETACHED  |  THR_SCOPE_SYSTEM) ==- 1 )
170           return   1 ;
171       if (ACE_Thread_Manager::instance() -> spawn(controller,reactor,THR_DETACHED  |  THR_SCOPE_SYSTEM) ==- 1 )
172           return   1 ;
173       return  ACE_Thread_Manager::instance() -> wait();
174  }
175 
176  static  ACE_THR_FUNC_RETURN run_events ( void   * arg)
177  {
178      ACE_Reactor *  reactor = ACE_static_cast(ACE_Reactor * ,arg);
179      ACE_INET_Addr addr(PORT_NO);
180 
181      Echo_Accept_Handler  * eh = 0 ;
182      ACE_NEW_RETURN(eh,Echo_Accept_Handler(addr), 1 );
183 
184      ACE_Reactor::instance() -> owner(ACE_OS::thr_self());
185      reactor -> register_handler(eh,ACE_Event_Handler::ACCEPT_MASK);
186      ACE_Reactor::instance() -> run_reactor_event_loop();
187       return   0 ;
188  }
189  static  ACE_THR_FUNC_RETURN controller ( void   * arg)
190  {
191      ACE_Reactor *  reactor = ACE_static_cast(ACE_Reactor * ,arg);
192      Quit_Handler  * quit_handler = 0 ;
193      ACE_NEW_RETURN(quit_handler,Quit_Handler(reactor), 1 );
194       for (;;)
195      {
196          std:: string  line;
197          std::getline(std::cin,line, ' \n ' );
198           if (line == " quit " ){
199              ACE_DEBUG((LM_DEBUG, " 请求停止服务器\n " ));
200              reactor -> notify(quit_handler);
201               break ;
202          }
203      }
204       return   0 ;  
205  }
文章转自庄周梦蝶  ,原文发布时间 2009-02-03
目录
相关文章
|
9天前
|
分布式计算 资源调度 Hadoop
Hadoop【问题记录 03】【ipc.Client: Retrying connect to server:xxx/:8032+InvalidResourceRequestException】解决
【4月更文挑战第2天】Hadoop【问题记录 03】【ipc.Client: Retrying connect to server:xxx/:8032+InvalidResourceRequestException】解决
25 2
Web server failed to start. Port XXX was already in use.【完美解决方案】
Web server failed to start. Port XXX was already in use.【完美解决方案】
Web server failed to start. Port XXX was already in use.【完美解决方案】
|
9月前
Web server failed to start. Port XXX was already in use.原因分析-解决方案
Web server failed to start. Port XXX was already in use.原因分析-解决方案
165 1
Web server failed to start. Port XXX was already in use.原因分析-解决方案
|
2月前
swing编写client端及多线程server端之server端
swing编写client端及多线程server端之server端
|
2月前
|
前端开发 JavaScript API
Server-Sent Events)
服务器发送事件(Server-Sent Events,简称SSE)是一种基于HTTP协议的实时通信技术,允许服务器向客户端推送实时消息。与传统的轮询和长轮询相比,SSE提供了更高效和实时的数据推送机制。
18 2
|
9月前
|
Web App开发 前端开发 安全
基础:BS(Browser/Server)、CS(Client/Server)架构
基础:BS(Browser/Server)、CS(Client/Server)架构
214 0
|
应用服务中间件 Android开发
“Server Tomcat v9.0 Server at localhost was unable to start within 45 seconds“的解决方案
“Server Tomcat v9.0 Server at localhost was unable to start within 45 seconds“的解决方案
517 0
“Server Tomcat v9.0 Server at localhost was unable to start within 45 seconds“的解决方案
|
网络协议 NoSQL Redis
Start_Redis Nov 21:11:04.422 # Creating Server TCP listening socket 127.0.0.1:6379: bind: No error
启动 redis-server.exe 报错19 Nov 21:11:04.422 # Creating Server TCP listening socket 127.0.0.1:6379: bind: No error
412 0
|
存储
通过echo_server带你入门brpc!
前文我们介绍过如何编译安装brpc(brpc最新安装上手指南),今天通过echo_server来介绍一下brpc的基本使用方法与细节。
715 0
|
C++ Windows
A simple IOCP Server/Client Class
  Download demo project v1.
1842 0