Merge pull request #2309 from mitza-oci/warnings
[ACE_TAO.git] / ACE / examples / Reactor / Dgram / CODgram.cpp
blobf8671b31e993afdaefdad26a528a13a19e5c938b
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
4 // be run in two ways:
5 //
6 // 1. Stand-alone -- e.g.,
7 //
8 // % ./CODgram
9 //
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.,
15 // # Peer1
16 // % ./CODgram 10002 tango.cs.wustl.edu 10003 peer1
18 // # 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.
37 static u_short port1;
39 class Dgram_Endpoint : public ACE_Event_Handler
41 public:
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,
49 const void *arg = 0);
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
59 private:
60 ACE_SOCK_CODgram endpoint_;
61 // Wrapper for sending/receiving dgrams.
64 int
65 Dgram_Endpoint::send (const char *buf, size_t len)
67 return this->endpoint_.send (buf, len);
70 int
71 Dgram_Endpoint::handle_close (ACE_HANDLE handle,
72 ACE_Reactor_Mask)
74 ACE_UNUSED_ARG (handle);
76 this->endpoint_.close ();
77 return 0;
80 Dgram_Endpoint::Dgram_Endpoint (const ACE_INET_Addr &remote_addr,
81 const ACE_INET_Addr &local_addr)
82 : endpoint_ (remote_addr, local_addr)
86 ACE_HANDLE
87 Dgram_Endpoint::get_handle () const
89 return this->endpoint_.get_handle ();
92 int
93 Dgram_Endpoint::handle_input (ACE_HANDLE)
95 char buf[BUFSIZ];
97 ACE_DEBUG ((LM_DEBUG,
98 "(%P|%t) activity occurred on handle %d!\n",
99 this->endpoint_.get_handle ()));
101 ssize_t n = this->endpoint_.recv (buf, sizeof buf);
103 if (n == -1)
104 ACE_ERROR ((LM_ERROR,
105 "%p\n",
106 "handle_input"));
107 else
108 ACE_DEBUG ((LM_DEBUG,
109 "(%P|%t) buf of size %d = %*s\n",
110 n, n, buf));
111 return 0;
115 Dgram_Endpoint::handle_timeout (const ACE_Time_Value &,
116 const void *)
118 ACE_DEBUG ((LM_DEBUG,
119 "(%P|%t) timed out for endpoint\n"));
120 return 0;
123 static int
124 run_test (u_short localport,
125 const ACE_TCHAR *remotehost,
126 u_short remoteport,
127 const ACE_TCHAR *peer)
129 ACE_INET_Addr remote_addr (remoteport,
130 remotehost);
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
137 (&endpoint,
138 ACE_Event_Handler::READ_MASK) == -1)
139 ACE_ERROR_RETURN ((LM_ERROR,
140 "ACE_Reactor::register_handler"),
141 -1);
142 char buf[BUFSIZ];
143 ACE_OS::strcpy (buf,
144 "Data to transmit");
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,
156 "(%P|%t) .\n"));
157 ACE_OS::sleep (1);
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,
168 "(%P|%t) %p\n",
169 "handle_events"),
170 -1);
171 ACE_DEBUG ((LM_DEBUG,
172 "(%P|%t) return from handle events\n"));
174 endpoint.send (buf, len);
176 ACE_DEBUG ((LM_DEBUG,
177 "(%P|%t) .\n"));
180 if (ACE_Reactor::instance ()->remove_handler
181 (&endpoint,
182 ACE_Event_Handler::READ_MASK) == -1)
183 ACE_ERROR_RETURN ((LM_ERROR,
184 "ACE_Reactor::remove_handler"),
185 -1);
186 ACE_DEBUG ((LM_DEBUG,
187 "(%P|%t) exiting\n"));
188 return 0;
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
202 // new program.
203 if (argc > 4)
204 run_test (port1,
205 remotehost,
206 port2,
207 argv[4]);
208 else
210 ACE_DEBUG ((LM_DEBUG,
211 "(%P|%t) local port = %d, remote host = %s, remote port = %d\n",
212 port1,
213 remotehost,
214 port2));
216 ACE_Process_Options options;
217 options.command_line (ACE_TEXT("%s %d %s %d %c"),
218 argv[0],
219 port1,
220 remotehost,
221 port2,
222 '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))
232 case -1:
233 return -1;
235 case 0:
236 run_test (port1,
237 remotehost,
238 port2,
239 ACE_TEXT("peer1"));
240 break;
242 default:
243 run_test (port2,
244 remotehost,
245 port1,
246 ACE_TEXT("peer2"));
247 new_process.wait ();
248 break;
252 return 0;