1 // Exercise the <ACE_SOCK_CODgram> wrapper along with the
2 // <ACE_Reactor>. This test simply ping-pongs datagrams back and
3 // forth between the peer1 and peer2 processes. This test can
6 // 1. Stand-alone -- e.g.,
10 // which will spawn a child process and run peer1 and peer2
11 // in different processes on the same machine.
13 // 2. Distributed -- e.g.,
16 // % ./CODgram 10002 tango.cs.wustl.edu 10003 peer1
19 // % ./CODgram 10003 tango.cs.wustl.edu 10002 peer2
21 // which will run peer1 and peer2 in different processes
22 // on the same or different machines. Note that you MUST
23 // give the name "peer1" as the final argument to one and
24 // only one of the programs so that the test will work properly.
26 #include "ace/OS_main.h"
27 #include "ace/OS_NS_string.h"
28 #include "ace/OS_NS_unistd.h"
29 #include "ace/Reactor.h"
30 #include "ace/SOCK_CODgram.h"
31 #include "ace/INET_Addr.h"
32 #include "ace/Process.h"
33 #include "ace/Log_Msg.h"
36 // Port used to receive for dgrams.
39 class Dgram_Endpoint
: public ACE_Event_Handler
42 Dgram_Endpoint (const ACE_INET_Addr
&remote_addr
,
43 const ACE_INET_Addr
&local_addr
);
45 // = Hook methods inherited from the <ACE_Event_Handler>.
46 virtual ACE_HANDLE
get_handle () const;
47 virtual int handle_input (ACE_HANDLE handle
);
48 virtual int handle_timeout (const ACE_Time_Value
& tv
,
51 virtual int handle_close (ACE_HANDLE handle
,
52 ACE_Reactor_Mask close_mask
);
54 //FUZZ: disable check_for_lack_ACE_OS
55 int send (const char *buf
, size_t len
);
56 // Send the <buf> to the peer.
57 //FUZZ: enable check_for_lack_ACE_OS
60 ACE_SOCK_CODgram endpoint_
;
61 // Wrapper for sending/receiving dgrams.
65 Dgram_Endpoint::send (const char *buf
, size_t len
)
67 return this->endpoint_
.send (buf
, len
);
71 Dgram_Endpoint::handle_close (ACE_HANDLE handle
,
74 ACE_UNUSED_ARG (handle
);
76 this->endpoint_
.close ();
80 Dgram_Endpoint::Dgram_Endpoint (const ACE_INET_Addr
&remote_addr
,
81 const ACE_INET_Addr
&local_addr
)
82 : endpoint_ (remote_addr
, local_addr
)
87 Dgram_Endpoint::get_handle () const
89 return this->endpoint_
.get_handle ();
93 Dgram_Endpoint::handle_input (ACE_HANDLE
)
98 "(%P|%t) activity occurred on handle %d!\n",
99 this->endpoint_
.get_handle ()));
101 ssize_t n
= this->endpoint_
.recv (buf
, sizeof buf
);
104 ACE_ERROR ((LM_ERROR
,
108 ACE_DEBUG ((LM_DEBUG
,
109 "(%P|%t) buf of size %d = %*s\n",
115 Dgram_Endpoint::handle_timeout (const ACE_Time_Value
&,
118 ACE_DEBUG ((LM_DEBUG
,
119 "(%P|%t) timed out for endpoint\n"));
124 run_test (u_short localport
,
125 const ACE_TCHAR
*remotehost
,
127 const ACE_TCHAR
*peer
)
129 ACE_INET_Addr
remote_addr (remoteport
,
131 ACE_INET_Addr
local_addr (localport
);
133 Dgram_Endpoint
endpoint (remote_addr
, local_addr
);
135 // Read data from other side.
136 if (ACE_Reactor::instance ()->register_handler
138 ACE_Event_Handler::READ_MASK
) == -1)
139 ACE_ERROR_RETURN ((LM_ERROR
,
140 "ACE_Reactor::register_handler"),
145 size_t len
= ACE_OS::strlen (buf
);
147 // "peer1" is the "initiator."
148 if (ACE_OS::strncmp (peer
, ACE_TEXT("peer1"), 5) == 0)
150 ACE_DEBUG ((LM_DEBUG
,
151 "(%P|%t) sending data\n"));
152 for (size_t i
= 0; i
< 20; i
++)
154 endpoint
.send (buf
, len
);
155 ACE_DEBUG ((LM_DEBUG
,
161 for (int i
= 0; i
< 40; i
++)
163 // Wait up to 10 seconds for data.
164 ACE_Time_Value
tv (10, 0);
166 if (ACE_Reactor::instance ()->handle_events (tv
) <= 0)
167 ACE_ERROR_RETURN ((LM_DEBUG
,
171 ACE_DEBUG ((LM_DEBUG
,
172 "(%P|%t) return from handle events\n"));
174 endpoint
.send (buf
, len
);
176 ACE_DEBUG ((LM_DEBUG
,
180 if (ACE_Reactor::instance ()->remove_handler
182 ACE_Event_Handler::READ_MASK
) == -1)
183 ACE_ERROR_RETURN ((LM_ERROR
,
184 "ACE_Reactor::remove_handler"),
186 ACE_DEBUG ((LM_DEBUG
,
187 "(%P|%t) exiting\n"));
192 ACE_TMAIN (int argc
, ACE_TCHAR
*argv
[])
194 // Estabish call backs and socket names.
196 port1
= argc
> 1 ? ACE_OS::atoi (argv
[1]) : ACE_DEFAULT_SERVER_PORT
;
197 const ACE_TCHAR
*remotehost
= argc
> 2 ? argv
[2] : ACE_DEFAULT_SERVER_HOST
;
198 const u_short port2
= argc
> 3 ? ACE_OS::atoi (argv
[3]) : port1
+ 1;
200 // Providing the fourth command line argument indicates we don't
201 // want to spawn a new process. On Win32, we use this to exec the
210 ACE_DEBUG ((LM_DEBUG
,
211 "(%P|%t) local port = %d, remote host = %s, remote port = %d\n",
216 ACE_Process_Options options
;
217 options
.command_line (ACE_TEXT("%s %d %s %d %c"),
224 // This has no effect on NT and will spawn a process that exec
225 // the above run_test function.
226 options
.creation_flags (ACE_Process_Options::NO_EXEC
);
228 ACE_Process new_process
;
230 switch (new_process
.spawn (options
))