1 // benchd: Adapted from the "ntalker" example.
4 #include "ace/Process.h"
5 #include "ace/INET_Addr.h"
6 #include "ace/SOCK_Dgram_Mcast.h"
7 #include "ace/Reactor.h"
8 #include "ace/Get_Opt.h"
10 #include "ace/OS_NS_stdio.h"
12 #if defined (ACE_HAS_IP_MULTICAST)
13 // network interface to subscribe to
14 // this is hardware specific.
15 // use netstat (1M) to find whether your interface
18 // Maximum number of arguments supported for a request
19 static const int MAX_ARGS
= 16;
20 // Name of the client benchmarking tool
21 static const char *TESTER
= "http_tester";
23 static const char *INTERFACE
= "le0";
24 static const char *MCAST_ADDR
= ACE_DEFAULT_MULTICAST_ADDR
;
25 static const u_short UDP_PORT
= ACE_DEFAULT_MULTICAST_PORT
;
26 static const char *OUTPUT_FILE_NAME
= "benchd.log";
27 static ACE_HANDLE OUTPUT_FILE
;
29 // Handle both multicast and stdin events.
31 class Handle_Events
: public ACE_Event_Handler
34 Handle_Events (u_short udp_port
,
36 const char *interface_
,
37 ACE_Reactor
&reactor
);
40 virtual int handle_input (ACE_HANDLE
);
41 virtual int handle_close (ACE_HANDLE
, ACE_Reactor_Mask
);
44 int serve (char *buf
);
45 ACE_SOCK_Dgram_Mcast mcast_
;
46 ACE_Handle_Set handle_set_
;
50 Handle_Events::handle_input (ACE_HANDLE h
)
56 int readresult
= ACE_OS::read (h
, buf
, BUFSIZ
);
59 if (this->mcast_
.send (buf
, readresult
) != readresult
)
61 ACE_OS::perror ("send error");
66 else if (readresult
== -1)
67 ACE_OS::perror ("can't read from STDIN");
73 ACE_INET_Addr remote_addr
;
75 // receive message from multicast group
76 int retcode
= this->mcast_
.recv (buf
, sizeof buf
, remote_addr
);
81 cout << "received datagram from host " << remote_addr.get_host_name ()
82 << " on port " << remote_addr.get_port_number ()
83 << " bytes = " << retcode << endl;
89 ACE_OS::perror ("Something amiss.");
95 Handle_Events::handle_close (ACE_HANDLE h
, ACE_Reactor_Mask
)
98 ACE_DEBUG ((LM_DEBUG
, "STDIN_Events handle removed from reactor.\n"));
100 ACE_DEBUG ((LM_DEBUG
, "Mcast_Events handle removed from reactor.\n"));
104 Handle_Events::~Handle_Events ()
106 // ACE_OS::exit on error (bogus)...
108 if (this->mcast_
.unsubscribe () == -1)
109 ACE_OS::perror ("unsubscribe fails"), ACE_OS::exit (1);
112 Handle_Events::Handle_Events (u_short udp_port
,
114 const char *interface_
,
115 ACE_Reactor
&reactor
)
117 // Create multicast address to listen on.
119 ACE_INET_Addr
sockmc_addr (udp_port
, ip_addr
);
121 // subscribe to multicast group.
123 if (this->mcast_
.subscribe (sockmc_addr
, 1, interface_
) == -1)
124 ACE_OS::perror ("can't subscribe to multicast group"), ACE_OS::exit (1);
126 // Disable loopbacks.
127 // if (this->mcast_.set_option (IP_MULTICAST_LOOP, 0) == -1 )
128 // ACE_OS::perror (" can't disable loopbacks " ), ACE_OS::exit (1);
131 this->handle_set_
.set_bit (0);
133 this->handle_set_
.set_bit (this->mcast_
.get_handle ());
135 // Register callbacks with the ACE_Reactor.
136 if (reactor
.register_handler (this->handle_set_
,
138 ACE_Event_Handler::READ_MASK
) == -1)
139 ACE_OS::perror ("can't register events"), ACE_OS::exit (1);
143 // This method handles multicast requests..
144 // These requests are of the following form:
145 // command (arguments)
148 // currently only one is supported (and indeed needed :-)) http_tester
152 Handle_Events::serve (char *buf
)
154 ACE_ARGV
arguments (buf
);
156 if (ACE_OS::strcmp (arguments
[0], TESTER
) == 0)
158 ACE_Process_Options po
;
161 po
.set_handles (ACE_INVALID_HANDLE
, OUTPUT_FILE
, OUTPUT_FILE
);
162 po
.command_line (arguments
.argv ());
172 parse_args (int argc
, ACE_TCHAR
*argv
[])
174 ACE_Get_Opt
get_opt (argc
, argv
, ACE_TEXT("i:u:q"));
178 while ((c
= get_opt ()) != -1)
184 INTERFACE
= get_opt
.opt_arg ();
187 // Usage, same as error
190 ACE_DEBUG ((LM_DEBUG
, "%s -i interface\n", argv
[0]));
195 static sig_atomic_t done
= 0;
206 ACE_TMAIN (int argc
, ACE_TCHAR
*argv
[])
208 ACE_Sig_Action
sa ((ACE_SignalHandler
) handler
, SIGINT
);
209 ACE_OS::signal (SIGCLD
, SIG_IGN
);
212 parse_args (argc
, argv
);
214 OUTPUT_FILE
= ACE_OS::open (OUTPUT_FILE_NAME
, O_CREAT
| O_WRONLY
, 0644);
215 if (OUTPUT_FILE
== 0)
219 Handle_Events
handle_events (UDP_PORT
, MCAST_ADDR
, INTERFACE
, reactor
);
224 reactor
.handle_events ();
226 ACE_OS::close (OUTPUT_FILE
);
227 cout
<< "\nbenchd done.\n";
232 ACE_TMAIN (int argc
, ACE_TCHAR
*argv
[])
234 ACE_ERROR ((LM_ERROR
, "error: %s must be run on a platform that support IP multicast\n",
238 #endif /* ACE_HAS_IP_MULTICAST */