1 //=============================================================================
3 * @file SOCK_Dgram_Bcast_Test.cpp
5 * This simple broadcast test is intended to check if ACE is capable
6 * of sending and receiving broadcasts. In single host environment most
7 * errors related to invalid broadcast initialization will not manifest
8 * themself, because usually broadcast on localhost interface works
9 * correctly. For this reason one should run also this test on two distinct
10 * hosts in single LAN.
11 * Tests that a call to open with an any address binds to the any address
12 * for the protocol passed in.
14 * @author Marek Brudka (mbrudka@elka.pw.edu.pl)
16 //=============================================================================
19 #include "test_config.h"
20 #include "ace/OS_NS_string.h"
21 #include "ace/OS_NS_unistd.h"
22 #include "ace/OS_NS_sys_time.h"
23 #include "ace/Log_Msg.h"
24 #include "ace/Get_Opt.h"
25 #include "ace/SOCK_Dgram_Bcast.h"
26 #include "ace/Thread_Manager.h"
27 #include "ace/Process.h"
28 #include "ace/Process_Manager.h"
30 static int dgram_port
= 14521;
31 static int dgrams_no
= 10;
32 static ACE_Time_Value
dgram_recv_timeout( 5, 0 );
33 static ACE_exitcode receiver_exit_code
= 0;
35 /*\brief Create and send single datagram
36 \param socket broadcast over this socket
37 \param datagram_no datagram identifier
38 \return -1 if error, 0 if OK
40 int send_datagram (ACE_SOCK_Dgram_Bcast
&socket
, int datagram_no
)
42 static char dgram_buffer
[BUFSIZ
];
44 ACE_OS::snprintf (dgram_buffer
, sizeof(dgram_buffer
),
45 "Datagram %d", datagram_no
);
46 if (socket
.send (dgram_buffer
,
47 ACE_OS::strlen (dgram_buffer
) + 1,
49 ACE_ERROR_RETURN ((LM_ERROR
, ACE_TEXT ("%p\n"),
50 ACE_TEXT ("Cannot broadcast datagram")), -1);
52 ACE_DEBUG ((LM_INFO
, ACE_TEXT ("%C sent\n"), dgram_buffer
));
56 /*\brief Send a sequence of datagrams with 1 second period
57 \note Th function employs dgram_port and dgrams_no global variables
64 ACE_TEXT ("Sending %d datagrams on port %d\n"),
67 ACE_SOCK_Dgram_Bcast socket
;
69 if (socket
.open (ACE_Addr::sap_any
) != -1)
71 while (dgrams_no
-- != 0)
73 if (send_datagram (socket
, dgrams_no
) < 0)
81 ACE_ERROR_RETURN ((LM_ERROR
, ACE_TEXT ("%p\n"),
82 ACE_TEXT ("Cannot open broadcast socket")), -1);
85 /*\brief Receive single datagram
86 \note The function employes dgram_port and dgram_recv_timeout variables
87 \retval -1 if not received,
88 \retval 0 received a datagrams
94 ACE_TEXT ("Receiving datagrams from port %d with timeout %d ms\n"),
95 dgram_port
, dgram_recv_timeout
.msec ()));
97 ACE_SOCK_Dgram socket
;
98 ACE_INET_Addr remote
;
99 static char dgram_buffer
[BUFSIZ
];
101 if (socket
.open (ACE_INET_Addr (dgram_port
)) != -1)
102 if (socket
.recv (dgram_buffer
, sizeof (dgram_buffer
),
103 remote
, 0, &dgram_recv_timeout
) > 0)
105 ACE_DEBUG ((LM_INFO
, ACE_TEXT ("%C received\n"), dgram_buffer
));
110 ACE_ERROR_RETURN ((LM_ERROR
, ACE_TEXT ("%p\n"),
111 ACE_TEXT ("Cannot receive datagrams")), -1);
115 ACE_ERROR_RETURN ((LM_ERROR
,
116 ACE_TEXT ("%p: %d\n"),
117 ACE_TEXT ("Cannot open broadcast socket on port"), dgram_port
), -1);
121 #if !defined (ACE_HAS_PROCESS_SPAWN) && defined (ACE_HAS_THREADS)
122 /* \brief Thread main function to run run_receiver function
123 \note run_receiver return valu is stored in receiver_exit_code global variable
125 static ACE_THR_FUNC_RETURN
run_thread_receiver (void *)
127 receiver_exit_code
= run_receiver ();
130 #endif /* !defined (ACE_HAS_PROCESS_SPAWN) && defined (ACE_HAS_THREADS) */
132 /* \brief Just runs automatic tests
134 Function sends a number of datagrams, spawns child thread or process and
135 tries to receive at least one datagram.
136 \retval 0 datagram was received
137 \retval -1 datagram was not received
139 int run_auto_test (const ACE_TCHAR
*prog_name
)
141 #if defined (ACE_HAS_PROCESS_SPAWN)
142 ACE_DEBUG ((LM_INFO
, ACE_TEXT ("Running auto_tests in process mode\n")));
144 ACE_Process_Options opts
;
146 opts
.command_line (ACE_TEXT ("%s -p %d -t %d -a -r"),
147 prog_name
, dgram_port
, static_cast<int>(dgram_recv_timeout
.msec ()));
148 if ((child_pid
= ACE_Process_Manager::instance ()->spawn (opts
)) == -1)
149 ACE_ERROR_RETURN ((LM_ERROR
, ACE_TEXT ("%p\n"), ACE_TEXT ("spawn_n()")), -1);
151 #elif defined (ACE_HAS_THREADS)
152 ACE_UNUSED_ARG (prog_name
);
153 ACE_DEBUG ((LM_INFO
, ACE_TEXT ("Running auto_tests in thread mode\n")));
154 if (ACE_Thread_Manager::instance ()->spawn (run_thread_receiver
) == -1)
155 ACE_ERROR_RETURN ((LM_ERROR
,
157 ACE_TEXT ("spawn_n ()")), -1);
159 ACE_ERROR_RETURN ((LM_ERROR
,
160 ACE_TEXT ("Cannot run in auto_test mode without fork or threads.\n")),
162 #endif /* defined (ACE_HAS_PROCESS_SPAWN) */
165 ACE_TEXT ("Sending datagrams on port %d in auto_test mode\n"),
168 ACE_SOCK_Dgram_Bcast socket
;
170 if (socket
.open (ACE_Addr::sap_any
) != -1)
172 // send datagrams until child finishes
175 send_datagram (socket
, dgrams_no
--);
176 ACE_Time_Value
child_timeout (1);
177 #if defined (ACE_HAS_PROCESS_SPAWN)
179 if (ACE_Process_Manager::instance ()->wait (child_pid
,
181 &receiver_exit_code
) == child_pid
)
183 #else /* ACE_HAS_THREADS */
184 // sleep 1 second or wait for child thread
185 child_timeout
+= ACE_OS::gettimeofday () ;
186 if (ACE_Thread_Manager::instance ()->wait (&child_timeout
) == 0)
191 ACE_DEBUG ((LM_INFO
, ACE_TEXT ("Child finished with %d exit code\n"),
192 receiver_exit_code
));
195 ACE_ERROR_RETURN ((LM_ERROR
, ACE_TEXT ("%p\n"),
196 ACE_TEXT ("Cannot open broadcast socket")), -1);
197 return (receiver_exit_code
);
202 ACE_OS::printf("Usage:SOCK_Dgram_Bast_Test [-p port] [-n dgrams_no] [-t timeout_ms] [-s] [-r]\n"
203 "\tp broadcast port [14521]\n"
204 "\tn number of datagrams to broadcast [30] (<0 infinite)\n"
205 "\tt timeout in seconds for receive [5] (<=0 infinite)\n"
206 "\ts send datagrams and exit\n"
207 "\tr receive one datagram and exit\n\n"
208 "\t run auto-test when no r and s option is passed\n"
209 "\t test failures are manifested by -1 exit value, otherwise 0\n");
212 int run_main (int argc
, ACE_TCHAR
*argv
[])
214 // parse options and run in appropriate mode
216 int auto_test_recv
= 0;
218 ACE_Get_Opt
opts (argc
, argv
, ACE_TEXT ("p:t:n:sra"));
219 while ((opt
= opts ()) != -1)
226 return (run_sender());
231 ACE_START_TEST (ACE_TEXT ("SOCK_Dgram_Bcast_Test_Child"));
232 result
= run_receiver ();
236 return (run_receiver ());
239 dgrams_no
= ACE_OS::atoi (opts
.opt_arg ());
242 dgram_recv_timeout
.msec (ACE_OS::atoi (opts
.opt_arg ()));
245 dgram_port
= ACE_OS::atoi (opts
.opt_arg ());
251 ACE_START_TEST (ACE_TEXT ("SOCK_Dgram_Bcast_Test"));
253 #ifndef ACE_LACKS_IOCTL
254 result
= run_auto_test (argc
> 0 ? argv
[0] : ACE_TEXT ("SOCK_Dgram_Bcast_Test"));