相對完整的修改版本
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,"停止伺服器中
\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>