1 // Listens to multicast address. After first message received, will
2 // listen for 5 more seconds. Prints Mbits/sec received from client.
4 #include "ace/OS_main.h"
5 #include "ace/OS_NS_unistd.h"
6 #include "ace/INET_Addr.h"
7 #include "ace/SOCK_Dgram_Mcast.h"
8 #include "ace/Reactor.h"
9 #include "ace/Get_Opt.h"
10 #include "ace/Thread_Manager.h"
11 #include "ace/Service_Config.h"
13 #if defined (ACE_HAS_IP_MULTICAST)
14 // Network interface to subscribe to. This is hardware specific. use
15 // netstat(1M) to find whether your interface is le0 or ie0
17 static const ACE_TCHAR
*INTERFACE
= 0;
18 static const char *MCAST_ADDR
= ACE_DEFAULT_MULTICAST_ADDR
;
19 static const u_short UDP_PORT
= ACE_DEFAULT_MULTICAST_PORT
;
21 class Handler
: public ACE_Event_Handler
24 // Handle both multicast and stdin events.
26 Handler (u_short udp_port
,
28 const ACE_TCHAR
*a_interface
,
35 // Event demuxer hooks.
36 virtual int handle_input (ACE_HANDLE
);
37 virtual int handle_close (ACE_HANDLE
,
39 virtual ACE_HANDLE
get_handle () const;
42 ACE_SOCK_Dgram_Mcast mcast_
;
45 ACE_INET_Addr sockmc_addr_
;
46 // Address to multicast to.
50 Handler::get_handle () const
52 return this->mcast_
.get_handle ();
56 Handler::handle_input (ACE_HANDLE h
)
62 ssize_t result
= ACE_OS::read (h
, buf
, BUFSIZ
);
66 if (this->mcast_
.send (buf
, result
) != result
)
67 ACE_ERROR_RETURN ((LM_ERROR
,
73 else if (result
== -1)
74 ACE_ERROR_RETURN ((LM_ERROR
,
76 "can't read from STDIN"),
80 ACE_Reactor::end_event_loop ();
86 ACE_INET_Addr remote_addr
;
88 // Receive message from multicast group.
89 ssize_t result
= this->mcast_
.recv (buf
,
96 "received datagram from host %s on port %d bytes = %d\n",
97 remote_addr
.get_host_name (),
98 remote_addr
.get_port_number (),
100 ACE_OS::write (ACE_STDERR
, buf
, result
);
101 ACE_DEBUG ((LM_DEBUG
,
106 ACE_ERROR_RETURN ((LM_ERROR
,
114 Handler::handle_close (ACE_HANDLE h
, ACE_Reactor_Mask
)
118 ACE_DEBUG ((LM_DEBUG
,
119 "STDIN_Events handle removed from reactor.\n"));
120 if (ACE_Reactor::instance ()->remove_handler
121 (this, ACE_Event_Handler::READ_MASK
) == -1)
122 ACE_ERROR_RETURN ((LM_ERROR
,
128 ACE_DEBUG ((LM_DEBUG
,
129 "Mcast_Events handle removed from reactor.\n"));
135 if (this->mcast_
.leave (sockmc_addr_
) == -1)
136 ACE_ERROR ((LM_ERROR
,
141 Handler::Handler (u_short udp_port
,
143 const ACE_TCHAR
*a_interface
,
144 ACE_Reactor
&reactor
)
146 // Create multicast address to listen on.
148 this->sockmc_addr_
= ACE_INET_Addr (udp_port
, ip_addr
);
150 // subscribe to multicast group.
152 if (this->mcast_
.join (sockmc_addr_
, 1, a_interface
) == -1)
153 ACE_ERROR ((LM_ERROR
,
155 "can't subscribe to multicast group"));
157 // Disable loopbacks.
158 // if (this->mcast_.set_option (IP_MULTICAST_LOOP, 0) == -1 )
159 // ACE_OS::perror (" can't disable loopbacks " ), ACE_OS::exit (1);
161 // Register callbacks with the ACE_Reactor.
162 else if (reactor
.register_handler (this->mcast_
.get_handle (),
164 ACE_Event_Handler::READ_MASK
) == -1)
165 ACE_ERROR ((LM_ERROR
,
167 "can't register with Reactor\n"));
168 // Register the STDIN handler.
169 else if (ACE_Event_Handler::register_stdin_handler (this,
170 ACE_Reactor::instance (),
171 ACE_Thread_Manager::instance ()) == -1)
172 ACE_ERROR ((LM_ERROR
,
174 "register_stdin_handler"));
178 parse_args (int argc
, ACE_TCHAR
*argv
[])
180 ACE_Get_Opt
get_opt (argc
, argv
, ACE_TEXT("i:u"));
184 while ((c
= get_opt ()) != -1)
188 INTERFACE
= get_opt
.opt_arg ();
191 // usage same as unknown.
194 ACE_DEBUG ((LM_DEBUG
,
202 ACE_TMAIN (int argc
, ACE_TCHAR
*argv
[])
204 parse_args (argc
, argv
);
206 Handler
handler (UDP_PORT
,
209 *ACE_Reactor::instance ());
211 // Run the event loop.
212 ACE_Reactor::run_event_loop ();
214 ACE_DEBUG ((LM_DEBUG
,
221 ACE_TMAIN (int, ACE_TCHAR
*argv
[])
223 ACE_ERROR_RETURN ((LM_ERROR
,
224 "error: %s must be run on a platform that support IP multicast\n",
228 #endif /* ACE_HAS_IP_MULTICAST */