1 // ===========================================================================
3 * @file SOCK_Send_Recv_Test_IPV6.cpp
5 * @brief This is a test of the <ACE_SOCK>'s various send and receive
8 * The test forks two processes or spawns two threads (depending upon
9 * the platform) and then executes client and server allowing them to
10 * connect and exchange data in ways designed to exercise the send
11 * and recv functions. Right now, it primarily tests the iov-like
12 * send and recv functions, but others should be added to completely
13 * cover the possible scenarios.
15 * @author Steve Huston <shuston@riverace.com>
16 * Brian Buesker <bbuesker@qualcomm.com>
18 // ============================================================================
20 #include "test_config.h"
21 #include "ace/OS_NS_sys_wait.h"
22 #include "ace/OS_NS_unistd.h"
23 #include "ace/Thread.h"
24 #include "ace/Thread_Manager.h"
25 #include "ace/Time_Value.h"
26 #include "ace/SOCK_Connector.h"
27 #include "ace/SOCK_Acceptor.h"
28 #include "ace/SOCK_Stream.h"
30 // Change to non-zero if test fails
31 static int Test_Result
= 0;
33 #if !defined (ACE_LACKS_FORK) || defined (ACE_HAS_THREADS)
35 // In test 3, a large amount of data is sent. The purpose is to overflow the
36 // TCP send window, causing the sender to block (it's a send_n). This value
37 // is the amount to send. The assumption is that no implementation has a
38 // receive window larger than 128K bytes. If one is found, this is the place
40 // For some odd reason, NT will try to send a single large buffer, but not
41 // multiple smaller ones that add up to the large size.
42 const size_t Test3_Send_Size
= 4*1024;
43 const size_t Test3_Loops
= 10;
44 const size_t Test3_Total_Size
= Test3_Send_Size
* Test3_Loops
;
47 #if defined (ACE_HAS_IPV6)
52 ACE_INET_Addr
*remote_addr
= reinterpret_cast<ACE_INET_Addr
*> (arg
);
53 ACE_INET_Addr
server_addr (remote_addr
->get_port_number (),
56 ACE_SOCK_Stream cli_stream
;
57 ACE_SOCK_Connector con
;
58 ACE_Time_Value
timeout (ACE_DEFAULT_TIMEOUT
);
61 ACE_TEXT ("(%P|%t) Connecting to port %d\n"),
62 server_addr
.get_port_number()));
64 // Initiate connection with server; don't wait forever
65 if (con
.connect (cli_stream
,
70 ACE_TEXT ("(%P|%t) %p\n"),
71 ACE_TEXT ("connection failed")));
77 ACE_TEXT ("(%P|%t) connected to %C\n"),
78 server_addr
.get_host_name ()));
80 //******************* TEST 1 ******************************
82 // Do a iovec sendv - send the 255 byte buffer in 5 chunks. The
83 // server will verify that the correct data is sent, and that there
84 // is no more and no less.
90 // The server will verify that this data pattern gets there intact.
92 for (i
= 0; i
< sizeof buffer
; ++i
)
93 buffer
[i
] = static_cast<u_char
> (i
);
97 iov
[0].iov_base
= reinterpret_cast<char *> (&buffer
[0]);
100 iov
[1].iov_base
= reinterpret_cast<char *> (&buffer
[50]);
103 iov
[2].iov_base
= reinterpret_cast<char *> (&buffer
[75]);
104 iov
[2].iov_len
= 150;
106 iov
[3].iov_base
= reinterpret_cast<char *> (&buffer
[225]);
109 iov
[4].iov_base
= reinterpret_cast<char *> (&buffer
[254]);
112 len
= cli_stream
.sendv (iov
, 5);
115 ACE_ERROR ((LM_ERROR
,
116 ACE_TEXT ("(%P|%t) %p\n"),
117 ACE_TEXT ("Test 1, sendv failed")));
121 ACE_TEST_ASSERT (len
== 255);
123 //******************* TEST 2 ******************************
125 // The same data is coming back - receive it using recv (size_t n,
126 // ...) and compare it to the original data.
129 // Give it a chance to get here
131 len
= cli_stream
.recv (4,
138 ACE_ERROR ((LM_ERROR
,
139 ACE_TEXT ("(%P|%t) %p; len is %d, but should be 255!\n"),
142 ACE_TEST_ASSERT (len
== 255);
144 for (i
= 0; i
< 255; i
++)
145 if (buffer2
[i
] != buffer
[i
])
147 ACE_ERROR ((LM_ERROR
,
148 ACE_TEXT ("(%P|%t) Test 2, rcvd byte %d is %d, not %d\n"),
149 i
, buffer2
[i
], buffer
[i
]));
153 //******************* TEST 3 ******************************
155 // Do a send_n of a large size. The receive should sleep some to
156 // cause the data reception to be delayed, which will fill up the
157 // TCP window and cause send_n to block at some point. The particular
158 // case this tests only needs to be exercised if the socket is
159 // non-blocking, so set that first.
162 char buff
[Test3_Send_Size
];
163 ACE_TEST_ASSERT (cli_stream
.enable (ACE_NONBLOCK
) != -1);
164 for (i
= 0; i
< Test3_Loops
; ++i
)
167 sent
= cli_stream
.send_n (buff
, sizeof (buff
));
168 if (sent
!= sizeof (buff
) && errno
!= 0)
170 ACE_ERROR ((LM_ERROR
,
171 ACE_TEXT ("(%P|%t) Test 3, pass %d, sent %d, %p\n"),
172 i
, sent
, ACE_TEXT ("error")));
173 Test_Result
= 1; // Fail
185 ACE_SOCK_Acceptor
*peer_acceptor
= (ACE_SOCK_Acceptor
*) arg
;
186 ACE_SOCK_Stream sock_str
;
187 ACE_INET_Addr cli_addr
;
188 ACE_Time_Value
timeout (ACE_DEFAULT_TIMEOUT
);
190 // Accept the connection over which the stream tests will run.
191 // Don't lock up if client doesn't connect
192 if (peer_acceptor
->accept (sock_str
,
196 ACE_ERROR ((LM_ERROR
,
197 ACE_TEXT ("(%P|%t) %p\n"),
198 ACE_TEXT ("accept")));
203 ACE_DEBUG ((LM_DEBUG
,
204 ACE_TEXT ("(%P|%t) client %C connected from %d\n"),
205 cli_addr
.get_host_name (),
206 cli_addr
.get_port_number ()));
208 //******************* TEST 1 ******************************
210 // Do a iovec recvv - the client should send 255 bytes, which we
211 // will be detected and read into a ACE-allocated buffer. Use a 5
212 // second timeout to give the client a chance to send it all.
221 iov
[0].iov_base
= reinterpret_cast<char *> (&buffer
[0]);
224 iov
[1].iov_base
= reinterpret_cast<char *> (&buffer
[75]);
225 iov
[1].iov_len
= 100;
227 iov
[2].iov_base
= reinterpret_cast<char *> (&buffer
[175]);
230 len
= sock_str
.recvv_n (iov
, 3);
233 ACE_ERROR ((LM_ERROR
,
234 ACE_TEXT ("(%P|%t) %p\n"),
235 ACE_TEXT ("Test 1, recvv failed")));
239 ACE_TEST_ASSERT (len
== 255);
240 for (i
= 0; i
< 255; i
++)
243 ACE_ERROR ((LM_ERROR
,
244 ACE_TEXT ("(%P|%t) Test 1, rcvd byte %d is %d, not %d\n"),
251 //******************* TEST 2 ******************************
253 // Send the buffer back, using send (size_t n, ...) in 3 pieces.
255 len
= sock_str
.send (6,
262 ACE_TEST_ASSERT (len
== 255);
264 //******************* TEST 3 ******************************
266 // The sender is testing send_n to make sure it blocks if the TCP
267 // window fills. So sleep here for a bit to avoid getting the data
268 // yet. Then just read and empty out the received data.
270 // Keep reading until the peer closes.
271 sock_str
.disable (ACE_NONBLOCK
);
273 size_t total_recv
= 0;
277 got
= sock_str
.recv (buffer
, sizeof (buffer
));
283 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("(%P|%t) Test 3 received %d bytes\n"),
286 if (total_recv
== Test3_Total_Size
)
288 if (got
!= 0 || errno
!= 0)
290 ACE_ERROR ((LM_ERROR
,
291 ACE_TEXT ("(%P|%t) Test 3 final recv status %d, expected 0\n"),
293 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("(%P|%t) %p\n"),
294 ACE_TEXT ("expected errno == 0, instead")));
295 Test_Result
= 1; // Fail
300 ACE_ERROR ((LM_ERROR
, ACE_TEXT ("(%P|%t) Test 3 expected %d %p\n"),
301 Test3_Total_Size
, ACE_TEXT ("bytes")));
310 #endif /*ACE_HAS_IPV6*/
312 #endif /* !ACE_LACKS_FORK || ACE_HAS_THREADS */
314 #if defined (ACE_HAS_IPV6)
319 ACE_SOCK_Acceptor peer_acceptor
;
321 // Create a server address.
322 ACE_INET_Addr server_addr
;
324 // Bind listener to any port and then find out what the port was.
325 if (peer_acceptor
.open (ACE_Addr::sap_any
, 0, AF_INET6
) == -1
326 || peer_acceptor
.get_local_addr (server_addr
) == -1)
327 ACE_ERROR ((LM_ERROR
,
328 ACE_TEXT ("(%P|%t) %p\n"),
332 ACE_DEBUG ((LM_DEBUG
,
333 ACE_TEXT ("(%P|%t) starting server at port %d\n"),
334 server_addr
.get_port_number ()));
336 #if !defined (ACE_LACKS_FORK)
337 switch (ACE_OS::fork (ACE_TEXT("child")))
340 ACE_ERROR ((LM_ERROR
,
341 ACE_TEXT ("(%P|%t) %p\n%a"),
342 ACE_TEXT ("fork failed"),
346 client (&server_addr
);
350 server (reinterpret_cast<void *> (&peer_acceptor
));
353 #elif defined (ACE_HAS_THREADS)
354 if (ACE_Thread_Manager::instance ()->spawn
355 (ACE_THR_FUNC (server
),
356 reinterpret_cast<void *> (&peer_acceptor
),
357 THR_NEW_LWP
| THR_DETACHED
) == -1)
358 ACE_ERROR ((LM_ERROR
,
359 ACE_TEXT ("(%P|%t) %p\n%a"),
360 ACE_TEXT ("thread create failed"),
363 if (ACE_Thread_Manager::instance ()->spawn
364 (ACE_THR_FUNC (client
),
365 reinterpret_cast<void *> (&server_addr
),
366 THR_NEW_LWP
| THR_DETACHED
) == -1)
367 ACE_ERROR ((LM_ERROR
,
368 ACE_TEXT ("(%P|%t) %p\n%a"),
369 ACE_TEXT ("thread create failed"),
372 // Wait for the threads to exit.
373 ACE_Thread_Manager::instance ()->wait ();
376 ACE_TEXT ("(%P|%t) ")
377 ACE_TEXT ("only one thread may be run ")
378 ACE_TEXT ("in a process on this platform\n")));
379 #endif /* ACE_HAS_THREADS */
381 peer_acceptor
.close ();
385 #endif /*ACE_HAS_IPV6*/
388 run_main (int, ACE_TCHAR
*[])
390 ACE_START_TEST (ACE_TEXT ("SOCK_Send_Recv_Test_IPV6"));
392 #if defined (ACE_HAS_IPV6)
394 #endif /* ACE_HAS_IPV6 */