1 // Exercise the <ACE_SOCK_Dgram> wrapper along with the <ACE_Reactor>.
2 // This test simply ping-pongs datagrams back and forth between the
3 // peer1 and peer2 processes. This test can be run in two ways:
5 // 1. Stand-alone -- e.g.,
9 // which will spawn a child process and run peer1 and peer2
10 // in different processes on the same machine.
12 // 2. Distributed -- e.g.,
15 // % ./Dgram 10002 tango.cs.wustl.edu 10003 peer1
18 // % ./Dgram 10003 tango.cs.wustl.edu 10002 peer2
20 // which will run peer1 and peer2 in different processes
21 // on the same or different machines. Note that you MUST
22 // give the name "peer1" as the final argument to one and
23 // only one of the programs so that the test will work properly.
25 #include "ace/OS_main.h"
26 #include "ace/OS_NS_string.h"
27 #include "ace/OS_NS_unistd.h"
28 #include "ace/Reactor.h"
29 #include "ace/Process.h"
30 #include "ace/SOCK_Dgram.h"
31 #include "ace/INET_Addr.h"
32 #include "ace/Log_Msg.h"
35 // Port used to receive for dgrams.
38 class Dgram_Endpoint
: public ACE_Event_Handler
41 Dgram_Endpoint (const ACE_INET_Addr
&local_addr
);
43 // = Hook methods inherited from the <ACE_Event_Handler>.
44 virtual ACE_HANDLE
get_handle () const;
45 virtual int handle_input (ACE_HANDLE handle
);
46 virtual int handle_timeout (const ACE_Time_Value
& tv
,
48 virtual int handle_close (ACE_HANDLE handle
,
49 ACE_Reactor_Mask close_mask
);
51 //FUZZ: disable check_for_lack_ACE_OS
52 int send (const char *buf
, size_t len
, const ACE_INET_Addr
&);
53 // Send the <buf> to the peer.
54 //FUZZ: enable check_for_lack_ACE_OS
57 ACE_SOCK_Dgram endpoint_
;
58 // Wrapper for sending/receiving dgrams.
62 Dgram_Endpoint::send (const char *buf
,
64 const ACE_INET_Addr
&addr
)
66 return this->endpoint_
.send (buf
, len
, addr
);
69 Dgram_Endpoint::Dgram_Endpoint (const ACE_INET_Addr
&local_addr
)
70 : endpoint_ (local_addr
)
75 Dgram_Endpoint::get_handle () const
77 return this->endpoint_
.get_handle ();
81 Dgram_Endpoint::handle_close (ACE_HANDLE handle
,
84 ACE_UNUSED_ARG (handle
);
86 this->endpoint_
.close ();
92 Dgram_Endpoint::handle_input (ACE_HANDLE
)
95 ACE_INET_Addr from_addr
;
98 "(%P|%t) activity occurred on handle %d!\n",
99 this->endpoint_
.get_handle ()));
101 ssize_t n
= this->endpoint_
.recv (buf
,
106 ACE_ERROR ((LM_ERROR
,
110 ACE_DEBUG ((LM_DEBUG
,
111 "(%P|%t) buf of size %d = %*s\n",
119 Dgram_Endpoint::handle_timeout (const ACE_Time_Value
&,
122 ACE_DEBUG ((LM_DEBUG
,
123 "(%P|%t) timed out for endpoint\n"));
128 run_test (u_short localport
,
129 const ACE_TCHAR
*remotehost
,
131 const ACE_TCHAR
*peer
)
133 ACE_INET_Addr
remote_addr (remoteport
,
135 ACE_INET_Addr
local_addr (localport
);
137 Dgram_Endpoint
*endpoint
;
139 ACE_NEW_RETURN (endpoint
,
140 Dgram_Endpoint (local_addr
),
143 // Read data from other side.
144 if (ACE_Reactor::instance ()->register_handler
146 ACE_Event_Handler::READ_MASK
) == -1)
147 ACE_ERROR_RETURN ((LM_ERROR
,
148 "ACE_Reactor::register_handler"),
152 ACE_OS::strcpy (buf
, "Data to transmit");
153 size_t len
= ACE_OS::strlen (buf
);
155 if (ACE_OS::strncmp (peer
, ACE_TEXT("peer1"), 5) == 0)
157 ACE_DEBUG ((LM_DEBUG
,
158 "(%P|%t) sending data\n"));
160 for (size_t i
= 0; i
< 20; i
++)
162 endpoint
->send (buf
, len
, remote_addr
);
163 ACE_DEBUG ((LM_DEBUG
,
169 for (int i
= 0; i
< 40; i
++)
171 // Wait up to 10 seconds for data.
172 ACE_Time_Value
tv (10, 0);
174 if (ACE_Reactor::instance ()->handle_events (tv
) <= 0)
175 ACE_ERROR_RETURN ((LM_DEBUG
,
180 ACE_DEBUG ((LM_DEBUG
,
181 "(%P|%t) return from handle events\n"));
183 endpoint
->send (buf
, len
, remote_addr
);
185 ACE_DEBUG ((LM_DEBUG
,
189 if (ACE_Reactor::instance ()->remove_handler
191 ACE_Event_Handler::READ_MASK
) == -1)
192 ACE_ERROR_RETURN ((LM_ERROR
,
193 "ACE_Reactor::remove_handler"),
195 ACE_DEBUG ((LM_DEBUG
,
196 "(%P|%t) exiting\n"));
201 ACE_TMAIN (int argc
, ACE_TCHAR
*argv
[])
203 // Estabish call backs and socket names.
205 port1
= argc
> 1 ? ACE_OS::atoi (argv
[1]) : ACE_DEFAULT_SERVER_PORT
;
206 const ACE_TCHAR
*remotehost
= argc
> 2 ? argv
[2] : ACE_DEFAULT_SERVER_HOST
;
207 const u_short port2
= argc
> 3 ? ACE_OS::atoi (argv
[3]) : port1
+ 1;
209 // Providing the fourth command line argument indicate we don't want
210 // to spawn a new process. On Win32, we use this to exec the new
213 run_test (port1
, remotehost
, port2
, argv
[4]);
216 ACE_DEBUG ((LM_DEBUG
,
217 "(%P|%t) local port = %d, remote host = %s, remote port = %d\n",
222 ACE_Process_Options options
;
223 options
.command_line (ACE_TEXT ("%s %d %s %d %c"),
230 // This has no effect on NT and will spawn a process that exec
231 // the above run_test function.
232 options
.creation_flags (ACE_Process_Options::NO_EXEC
);
234 ACE_Process new_process
;
235 switch (new_process
.spawn (options
))