2 //=============================================================================
6 * receive methods, over HTBP. The test forks two processes or spawns
7 * two threads (depending upon the platform) and then executes client
8 * and server allowing them to connect and exchange data in ways
9 * designed to exercise the send and recv functions.
11 * Right now, it primarily tests the iov-like send and recv
12 * functions, but others should be added to completely cover the
15 * @author Steve Huston <shuston@riverace.com>
17 //=============================================================================
20 #include "ace/HTBP/HTBP_Stream.h"
21 #include "ace/HTBP/HTBP_Session.h"
22 #include "ace/HTBP/HTBP_ID_Requestor.h"
23 #include "ace/HTBP/HTBP_Environment.h"
25 #include "ace/Thread.h"
26 #include "ace/Thread_Manager.h"
27 #include "ace/SOCK_Connector.h"
28 #include "ace/SOCK_Acceptor.h"
29 #include "ace/SOCK_Stream.h"
30 #include "ace/Get_Opt.h"
31 #include "ace/OS_NS_stdio.h"
32 #include "ace/OS_NS_sys_socket.h"
33 #include "ace/os_include/os_netdb.h"
35 // Change to non-zero if test fails
36 static int Test_Result
= 0;
38 // In test 3, a large amount of data is sent. The purpose is to overflow the
39 // TCP send window, causing the sender to block (it's a send_n). This value
40 // is the amount to send. The assumption is that no implementation has a
41 // receive window larger than 128K bytes. If one is found, this is the place
43 // For some odd reason, NT will try to send a single large buffer, but not
44 // multiple smaller ones that add up to the large size.
45 const size_t Test3_Send_Size
= 4*1024;
46 const size_t Test3_Loops
= 10;
47 const size_t Test3_Total_Size
= Test3_Send_Size
* Test3_Loops
;
49 const ACE_TCHAR
*notifier_file
= 0;
52 parse_args (int argc
, ACE_TCHAR
*argv
[])
54 ACE_Get_Opt
get_opts (argc
, argv
, ACE_TEXT("o:p:"));
57 while ((c
= get_opts ()) != -1)
61 notifier_file
= get_opts
.opt_arg();
64 port
= static_cast<unsigned>(ACE_OS::atoi (get_opts
.opt_arg()));
68 ACE_ERROR_RETURN ((LM_ERROR
,
75 // Indicates successful parsing of the command line
80 ACE_TMAIN (int argc
, ACE_TCHAR
*argv
[])
82 ACE_OS::socket_init (ACE_WSOCK_VERSION
);
84 if (parse_args(argc
, argv
) != 0)
88 ACE_SOCK_Acceptor peer_acceptor
;
90 // Create a server address.
91 ACE_INET_Addr server_addr
;
93 char hostname
[BUFSIZ
];
95 if (ACE_OS::hostname (hostname
, BUFSIZ
) != 0)
98 ACE_TEXT ("Could not get the hostname\n")));
101 ACE::HTBP::Addr
addr (port
, hostname
);
103 // Bind listener to any port and then find out what the port was.
104 if (peer_acceptor
.open (addr
) == -1
105 || peer_acceptor
.get_local_addr (server_addr
) == -1)
106 ACE_ERROR_RETURN ((LM_ERROR
,
107 ACE_TEXT ("(%P|%t) %p\n"),
108 ACE_TEXT ("open")), 1);
110 ACE_DEBUG ((LM_DEBUG
,
111 ACE_TEXT ("(%P|%t) starting server at port %d\n"),
112 server_addr
.get_port_number ()));
114 if (notifier_file
!= 0)
116 FILE *f
= ACE_OS::fopen (notifier_file
,ACE_TEXT("w+"));
117 const char *msg
= "server ready";
118 ACE_OS::fwrite (msg
,ACE_OS::strlen(msg
),1,f
);
122 ACE_INET_Addr cli_addr
;
124 ACE_SOCK_Stream sock_stream
[2];
125 ACE_DEBUG ((LM_DEBUG
,"(%P) server is ready\n"));
127 if (peer_acceptor
.accept(sock_stream
[0],&cli_addr
,0) == -1)
129 ACE_ERROR ((LM_ERROR
,
130 ACE_TEXT ("(%P|%t) %p\n"),
131 ACE_TEXT ("accept")));
135 ACE::HTBP::Channel
channel1(sock_stream
[0]);
136 ACE_DEBUG ((LM_DEBUG
,
137 ACE_TEXT("(%P) Got sock[0], handle = %d\n"),
138 sock_stream
[0].get_handle()));
140 if (peer_acceptor
.accept(sock_stream
[1],&cli_addr
,0) == -1)
142 ACE_ERROR ((LM_ERROR
,
143 ACE_TEXT ("(%P|%t) %p\n"),
144 ACE_TEXT ("accept")));
148 ACE::HTBP::Channel
channel2(sock_stream
[1]);
149 ACE_DEBUG ((LM_DEBUG
,
150 ACE_TEXT("(%P) Got sock_stream[1], handle = %d\n"),
151 sock_stream
[1].get_handle()));
153 while ((res
= channel1
.pre_recv()) != 0)
155 ACE_DEBUG ((LM_DEBUG
,
156 ACE_TEXT("(%P)res = %d. waiting 1 sec. %p\n"),
158 ACE_TEXT("stream.pre_recv()")));
162 ACE_DEBUG ((LM_DEBUG
,
163 ACE_TEXT("(%P)Read from channel2\n")));
164 while ((res
= channel2
.pre_recv()) != 0)
166 ACE_DEBUG ((LM_DEBUG
,
167 ACE_TEXT("(%P)res = %d, waiting 1 sec. %p\n"),res
,
168 ACE_TEXT("stream2.pre_recv()")));
172 ACE::HTBP::Session
*session
= channel1
.session();
173 ACE::HTBP::Stream
stream (session
);
175 ACE_DEBUG ((LM_DEBUG
,
176 ACE_TEXT ("(%P|%t) client %C connected from %d\n"),
177 cli_addr
.get_host_name (),
178 cli_addr
.get_port_number ()));
180 ACE_DEBUG ((LM_DEBUG
,
181 ACE_TEXT("(%P) ***** server TEST 1 *****\n")));
182 //******************* TEST 1 ******************************
184 // Do a iovec recvv - the client should send 255 bytes, which we
185 // will be detected and read into a ACE-allocated buffer. Use a 5
186 // second timeout to give the client a chance to send it all.
197 iov
[0].iov_base
= reinterpret_cast<char *> (&buffer
[0]);
200 iov
[1].iov_base
= reinterpret_cast<char *> (&buffer
[75]);
201 iov
[1].iov_len
= 100;
203 iov
[2].iov_base
= reinterpret_cast<char *> (&buffer
[175]);
206 len
= stream
.recvv (iov
, 3);
209 ACE_ERROR ((LM_ERROR
,
210 ACE_TEXT ("(%P|%t) %p\n"),
211 ACE_TEXT ("Test 1, recvv failed")));
215 ACE_DEBUG ((LM_DEBUG
,
216 ACE_TEXT("(%P) server, Test 1: recvd len = %d\n"),len
));
218 for (i
= 0; i
< 255; i
++)
221 ACE_ERROR ((LM_ERROR
,
222 ACE_TEXT ("(%P|%t) Test 1, rcvd byte %d is %d, not %d\n"),
229 ACE_DEBUG ((LM_DEBUG
,
230 ACE_TEXT("(%P) ***** server TEST 2 *****\n")));
232 //******************* TEST 2 ******************************
234 // Send the buffer back, using send (size_t n, ...) in 3 pieces.
236 len
= stream
.send (buffer
, 6);
237 len
+= stream
.send (buffer
+ 6,42);
238 len
+= stream
.send (buffer
+ 48,189);
239 len
+= stream
.send (buffer
+ 237,18);
240 ACE_DEBUG ((LM_DEBUG
,
241 ACE_TEXT("(%P) server sent len=%d\n"),len
));
242 // ACE_OS::sleep(10);
243 ACE_DEBUG ((LM_DEBUG
,
244 ACE_TEXT("(%P) flushing outbound queue\n")));
246 while ((res
= channel1
.pre_recv()) != 0 &&
247 (res
= channel2
.pre_recv()) != 0)
249 ACE_DEBUG ((LM_DEBUG
,
250 ACE_TEXT("(%P)res = %d. waiting 1 sec. %p\n"),
252 ACE_TEXT("stream.pre_recv()")));
255 ACE_DEBUG ((LM_DEBUG
,
256 ACE_TEXT("(%P)Read from channel2\n")));
258 int result
= session
->flush_outbound_queue();
260 ACE_DEBUG ((LM_DEBUG
,
261 ACE_TEXT("(%P) server: shutting down, flush returned %d\n"), result
));
263 ACE_OS::sleep(1); // prevent test failure on windows when the connection
266 sock_stream
[0].close();
267 sock_stream
[1].close();
270 peer_acceptor
.close ();
275 ACE_ERROR ((LM_ERROR
,
276 ACE_TEXT("(%P} server: send result %d != 255\n"), len
));