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.
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
,
26 else if (stream
.get_remote_addr (cli_addr
) == -1)
27 ACE_ERROR_RETURN ((LM_ERROR
,
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;
42 // Read data from client (terminate on error).
48 ssize_t r_bytes
= stream
.recv_n ((void *) &len
,
57 else if (r_bytes
== 0)
60 "(%P|%t) reached end of input, connection closed by client\n"));
63 else if (r_bytes
!= sizeof (ACE_INT32
))
73 ACE_NEW_RETURN (request
,
78 // Subtract off the sizeof the length prefix.
79 r_bytes
= stream
.recv_n (request
,
80 len
- sizeof (ACE_UINT32
));
88 else if (r_bytes
== 0)
91 "(%P|%t) reached end of input, connection closed by client\n"));
95 && ACE::write_n (ACE_STDOUT
,
101 else if (stream
.send_n (request
,
103 ACE_ERROR ((LM_ERROR
,
107 total_bytes
+= size_t (r_bytes
);
114 // Close new endpoint (listening endpoint stays open).
121 // Function entry point into the oneway server task.
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
,
134 else if (stream
.get_remote_addr (cli_addr
) == -1)
135 ACE_ERROR_RETURN ((LM_ERROR
,
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 ()));
146 ACE_Profile_Timer timer
;
149 size_t total_bytes
= 0;
150 size_t message_count
= 0;
154 // Read data from client (terminate on error).
160 ssize_t r_bytes
= stream
.recv_n ((void *) &len
,
164 ACE_ERROR ((LM_ERROR
,
169 else if (r_bytes
== 0)
171 ACE_DEBUG ((LM_DEBUG
,
172 "(%P|%t) reached end of input, connection closed by client\n"));
175 else if (r_bytes
!= sizeof (ACE_INT32
))
177 ACE_ERROR ((LM_ERROR
,
185 ACE_NEW_RETURN (request
,
190 // Subtract off the sizeof the length prefix.
191 r_bytes
= stream
.recv_n (request
,
192 len
- sizeof (ACE_UINT32
));
196 ACE_ERROR ((LM_ERROR
,
201 else if (r_bytes
== 0)
203 ACE_DEBUG ((LM_DEBUG
,
204 "(%P|%t) reached end of input, connection closed by client\n"));
208 && ACE::write_n (ACE_STDOUT
, request
, r_bytes
) != r_bytes
)
209 ACE_ERROR ((LM_ERROR
,
213 total_bytes
+= size_t (r_bytes
);
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"),
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"),
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).
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
,
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
,
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.
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,
305 ACE_ERROR ((LM_ERROR
,
308 else if (result
== 0 && verbose
)
309 ACE_DEBUG ((LM_DEBUG
,
310 "(%P|%t) select timed out\n"));
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
);
320 ACE_ERROR ((LM_ERROR
,
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"));
340 ACE_DEBUG ((LM_DEBUG
,
341 "(%P|%t) spawning oneway server\n"));
343 // Run the oneway server.
344 oneway_server (new_stream
);
353 ACE_TMAIN (int argc
, ACE_TCHAR
*argv
[])
355 u_short port
= ACE_DEFAULT_SERVER_PORT
;
358 port
= ACE_OS::atoi (argv
[1]);
360 return run_event_loop (port
);