Merge pull request #2216 from jwillemsen/jwi-cxxversionchecks
[ACE_TAO.git] / ACE / examples / IPC_SAP / SSL_SAP / SSL-server-simple.cpp
blobb6cae2fe044ab58725746e634171c7fc87d5ce77
1 // This example tests the features of the <ACE_SSL_SOCK_Acceptor>,
2 // <ACE_SSL_SOCK_Stream>, and <ACE_Svc_Handler> classes.
4 #include "ace/Thread_Manager.h"
5 #include "ace/Handle_Set.h"
6 #include "ace/Profile_Timer.h"
7 #include "ace/OS_NS_sys_select.h"
8 #include "ace/SSL/SSL_SOCK_Acceptor.h"
10 // Are we running verbosely?
11 static bool verbose = true;
13 // Function entry point into the twoway server task.
15 int
16 twoway_server (ACE_SSL_SOCK_Stream &stream)
18 ACE_INET_Addr cli_addr;
20 // Make sure we're not in non-blocking mode.
21 if (stream.disable (ACE_NONBLOCK) == -1)
22 ACE_ERROR_RETURN ((LM_ERROR,
23 "%p\n",
24 "disable"),
25 0);
26 else if (stream.get_remote_addr (cli_addr) == -1)
27 ACE_ERROR_RETURN ((LM_ERROR,
28 "%p\n",
29 "get_remote_addr"),
30 0);
32 ACE_DEBUG ((LM_DEBUG,
33 "(%P|%t) client %s connected from %d\n",
34 cli_addr.get_host_name (),
35 cli_addr.get_port_number ()));
37 size_t total_bytes = 0;
38 size_t message_count = 0;
40 char *request = 0;
42 // Read data from client (terminate on error).
44 for (;;)
46 ACE_INT32 len;
48 ssize_t r_bytes = stream.recv_n ((void *) &len,
49 sizeof (ACE_INT32));
50 if (r_bytes == -1)
52 ACE_ERROR ((LM_ERROR,
53 "%p\n",
54 "recv"));
55 break;
57 else if (r_bytes == 0)
59 ACE_DEBUG ((LM_DEBUG,
60 "(%P|%t) reached end of input, connection closed by client\n"));
61 break;
63 else if (r_bytes != sizeof (ACE_INT32))
65 ACE_ERROR ((LM_ERROR,
66 "(%P|%t) %p\n",
67 "recv_n failed"));
68 break;
70 else
72 len = ntohl (len);
73 ACE_NEW_RETURN (request,
74 char [len],
75 0);
78 // Subtract off the sizeof the length prefix.
79 r_bytes = stream.recv_n (request,
80 len - sizeof (ACE_UINT32));
81 if (r_bytes == -1)
83 ACE_ERROR ((LM_ERROR,
84 "%p\n",
85 "recv"));
86 break;
88 else if (r_bytes == 0)
90 ACE_DEBUG ((LM_DEBUG,
91 "(%P|%t) reached end of input, connection closed by client\n"));
92 break;
94 else if (verbose
95 && ACE::write_n (ACE_STDOUT,
96 request,
97 r_bytes) != r_bytes)
98 ACE_ERROR ((LM_ERROR,
99 "%p\n",
100 "ACE::write_n"));
101 else if (stream.send_n (request,
102 r_bytes) != r_bytes)
103 ACE_ERROR ((LM_ERROR,
104 "%p\n",
105 "send_n"));
107 total_bytes += size_t (r_bytes);
108 message_count++;
110 delete [] request;
111 request = 0;
114 // Close new endpoint (listening endpoint stays open).
115 stream.close ();
117 delete [] request;
118 return 0;
121 // Function entry point into the oneway server task.
123 static int
124 oneway_server (ACE_SSL_SOCK_Stream &stream)
126 ACE_INET_Addr cli_addr;
128 // Make sure we're not in non-blocking mode.
129 if (stream.disable (ACE_NONBLOCK) == -1)
130 ACE_ERROR_RETURN ((LM_ERROR,
131 "%p\n",
132 "disable"),
134 else if (stream.get_remote_addr (cli_addr) == -1)
135 ACE_ERROR_RETURN ((LM_ERROR,
136 "%p\n",
137 "get_remote_addr"),
140 ACE_DEBUG ((LM_DEBUG,
141 "(%P|%t) client %s connected from %d\n",
142 cli_addr.get_host_name (),
143 cli_addr.get_port_number ()));
145 // Timer business
146 ACE_Profile_Timer timer;
147 timer.start ();
149 size_t total_bytes = 0;
150 size_t message_count = 0;
152 char *request = 0;
154 // Read data from client (terminate on error).
156 for (;;)
158 ACE_INT32 len;
160 ssize_t r_bytes = stream.recv_n ((void *) &len,
161 sizeof (ACE_INT32));
162 if (r_bytes == -1)
164 ACE_ERROR ((LM_ERROR,
165 "%p\n",
166 "recv"));
167 break;
169 else if (r_bytes == 0)
171 ACE_DEBUG ((LM_DEBUG,
172 "(%P|%t) reached end of input, connection closed by client\n"));
173 break;
175 else if (r_bytes != sizeof (ACE_INT32))
177 ACE_ERROR ((LM_ERROR,
178 "(%P|%t) %p\n",
179 "recv_n failed"));
180 break;
182 else
184 len = ntohl (len);
185 ACE_NEW_RETURN (request,
186 char [len],
190 // Subtract off the sizeof the length prefix.
191 r_bytes = stream.recv_n (request,
192 len - sizeof (ACE_UINT32));
194 if (r_bytes == -1)
196 ACE_ERROR ((LM_ERROR,
197 "%p\n",
198 "recv"));
199 break;
201 else if (r_bytes == 0)
203 ACE_DEBUG ((LM_DEBUG,
204 "(%P|%t) reached end of input, connection closed by client\n"));
205 break;
207 else if (verbose
208 && ACE::write_n (ACE_STDOUT, request, r_bytes) != r_bytes)
209 ACE_ERROR ((LM_ERROR,
210 "%p\n",
211 "ACE::write_n"));
213 total_bytes += size_t (r_bytes);
214 message_count++;
216 delete [] request;
217 request = 0;
220 timer.stop ();
222 ACE_Profile_Timer::ACE_Elapsed_Time et;
223 timer.elapsed_time (et);
225 ACE_DEBUG ((LM_DEBUG,
226 ACE_TEXT ("\t\treal time = %f secs \n\t\tuser time = %f secs \n\t\tsystem time = %f secs\n"),
227 et.real_time,
228 et.user_time,
229 et.system_time));
231 double messages_per_sec = double (message_count) / et.real_time;
233 ACE_DEBUG ((LM_DEBUG,
234 ACE_TEXT ("\t\tmessages = %d\n\t\ttotal bytes = %d\n\t\tmbits/sec = %f\n\t\tusec-per-message = %f\n\t\tmessages-per-second = %0.00f\n"),
235 message_count,
236 total_bytes,
237 (((double) total_bytes * 8) / et.real_time) / (double) (1024 * 1024),
238 (et.real_time / (double) message_count) * 1000000,
239 messages_per_sec < 0 ? 0 : messages_per_sec));
241 // Close new endpoint (listening endpoint stays open).
242 stream.close ();
244 delete [] request;
245 return 0;
248 static int
249 run_event_loop (u_short port)
251 // Raise the socket handle limit to the maximum.
252 ACE::set_handle_limit ();
254 // Create the oneway and twoway acceptors.
255 ACE_SSL_SOCK_Acceptor twoway_acceptor;
256 ACE_SSL_SOCK_Acceptor oneway_acceptor;
258 // Create the oneway and twoway server addresses.
259 ACE_INET_Addr twoway_server_addr (port);
260 ACE_INET_Addr oneway_server_addr (port + 1);
262 // Create acceptors, reuse the address.
263 if (twoway_acceptor.open (twoway_server_addr, 1) == -1
264 || oneway_acceptor.open (oneway_server_addr, 1) == -1)
265 ACE_ERROR_RETURN ((LM_ERROR,
266 "%p\n",
267 "open"),
269 else if (twoway_acceptor.get_local_addr (twoway_server_addr) == -1
270 || oneway_acceptor.get_local_addr (oneway_server_addr) == -1)
271 ACE_ERROR_RETURN ((LM_ERROR,
272 "%p\n",
273 "get_local_addr"),
276 ACE_DEBUG ((LM_DEBUG,
277 "(%P|%t) starting twoway server at port %d and oneway server at port %d\n",
278 twoway_server_addr.get_port_number (),
279 oneway_server_addr.get_port_number ()));
281 // Keep these objects out here to prevent excessive constructor
282 // calls within the loop.
283 ACE_SSL_SOCK_Stream new_stream;
285 ACE_Handle_Set handle_set;
286 handle_set.set_bit (twoway_acceptor.get_handle ());
287 handle_set.set_bit (oneway_acceptor.get_handle ());
289 // Performs the iterative server activities.
291 for (;;)
293 ACE_Time_Value timeout (ACE_DEFAULT_TIMEOUT);
294 ACE_Handle_Set temp = handle_set;
296 int maxfd = int(oneway_acceptor.get_handle ());
297 if (maxfd < int(twoway_acceptor.get_handle ()))
298 maxfd = int(twoway_acceptor.get_handle ());
299 int result = ACE_OS::select (maxfd + 1,
300 (fd_set *) temp,
303 timeout);
304 if (result == -1)
305 ACE_ERROR ((LM_ERROR,
306 "(%P|%t) %p\n",
307 "select"));
308 else if (result == 0 && verbose)
309 ACE_DEBUG ((LM_DEBUG,
310 "(%P|%t) select timed out\n"));
311 else
313 if (temp.is_set (twoway_acceptor.get_handle ()))
315 int r = twoway_acceptor.accept (new_stream);
316 while (r == -1 && errno == EAGAIN)
317 r = twoway_acceptor.accept (new_stream);
318 if (r == -1)
320 ACE_ERROR ((LM_ERROR,
321 "%p\n",
322 "accept"));
323 continue;
325 else
326 ACE_DEBUG ((LM_DEBUG,
327 "(%P|%t) spawning twoway server\n"));
329 // Run the twoway server.
330 twoway_server (new_stream);
332 if (temp.is_set (oneway_acceptor.get_handle ()))
334 if (oneway_acceptor.accept (new_stream) == -1)
336 ACE_ERROR ((LM_ERROR, "%p\n", "accept"));
337 continue;
339 else
340 ACE_DEBUG ((LM_DEBUG,
341 "(%P|%t) spawning oneway server\n"));
343 // Run the oneway server.
344 oneway_server (new_stream);
349 /* NOTREACHED */
353 ACE_TMAIN (int argc, ACE_TCHAR *argv[])
355 u_short port = ACE_DEFAULT_SERVER_PORT;
357 if (argc > 1)
358 port = ACE_OS::atoi (argv[1]);
360 return run_event_loop (port);