天天看點

ACE Reactor的Echo Server

相對完整的修改版本

  1 /************************************************************************ 

  2 * @file: echo.cpp                                                    

  3 * @author: dennis

  4 * @revise: dennis <[email protected]> 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,"停止伺服器中

ACE Reactor的Echo Server

\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 <b></b>

繼續閱讀