1 | // |
2 | // tcp.cpp |
3 | // ~~~~~~~ |
4 | // |
5 | // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) |
6 | // |
7 | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
8 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
9 | // |
10 | |
11 | // Disable autolinking for unit tests. |
12 | #if !defined(BOOST_ALL_NO_LIB) |
13 | #define BOOST_ALL_NO_LIB 1 |
14 | #endif // !defined(BOOST_ALL_NO_LIB) |
15 | |
16 | // Enable cancel() support on Windows. |
17 | #define BOOST_ASIO_ENABLE_CANCELIO 1 |
18 | |
19 | // Test that header file is self-contained. |
20 | #include <boost/asio/ip/tcp.hpp> |
21 | |
22 | #include <cstring> |
23 | #include <boost/asio/io_service.hpp> |
24 | #include <boost/asio/read.hpp> |
25 | #include <boost/asio/write.hpp> |
26 | #include "../unit_test.hpp" |
27 | #include "../archetypes/gettable_socket_option.hpp" |
28 | #include "../archetypes/async_result.hpp" |
29 | #include "../archetypes/io_control_command.hpp" |
30 | #include "../archetypes/settable_socket_option.hpp" |
31 | |
32 | #if defined(BOOST_ASIO_HAS_BOOST_ARRAY) |
33 | # include <boost/array.hpp> |
34 | #else // defined(BOOST_ASIO_HAS_BOOST_ARRAY) |
35 | # include <array> |
36 | #endif // defined(BOOST_ASIO_HAS_BOOST_ARRAY) |
37 | |
38 | #if defined(BOOST_ASIO_HAS_BOOST_BIND) |
39 | # include <boost/bind.hpp> |
40 | #else // defined(BOOST_ASIO_HAS_BOOST_BIND) |
41 | # include <functional> |
42 | #endif // defined(BOOST_ASIO_HAS_BOOST_BIND) |
43 | |
44 | //------------------------------------------------------------------------------ |
45 | |
46 | // ip_tcp_compile test |
47 | // ~~~~~~~~~~~~~~~~~~~ |
48 | // The following test checks that all nested classes, enums and constants in |
49 | // ip::tcp compile and link correctly. Runtime failures are ignored. |
50 | |
51 | namespace ip_tcp_compile { |
52 | |
53 | void test() |
54 | { |
55 | using namespace boost::asio; |
56 | namespace ip = boost::asio::ip; |
57 | |
58 | try |
59 | { |
60 | io_service ios; |
61 | ip::tcp::socket sock(ios); |
62 | |
63 | // no_delay class. |
64 | |
65 | ip::tcp::no_delay no_delay1(true); |
66 | sock.set_option(no_delay1); |
67 | ip::tcp::no_delay no_delay2; |
68 | sock.get_option(option&: no_delay2); |
69 | no_delay1 = true; |
70 | (void)static_cast<bool>(no_delay1); |
71 | (void)static_cast<bool>(!no_delay1); |
72 | (void)static_cast<bool>(no_delay1.value()); |
73 | } |
74 | catch (std::exception&) |
75 | { |
76 | } |
77 | } |
78 | |
79 | } // namespace ip_tcp_compile |
80 | |
81 | //------------------------------------------------------------------------------ |
82 | |
83 | // ip_tcp_runtime test |
84 | // ~~~~~~~~~~~~~~~~~~~ |
85 | // The following test checks the runtime operation of the ip::tcp class. |
86 | |
87 | namespace ip_tcp_runtime { |
88 | |
89 | void test() |
90 | { |
91 | using namespace boost::asio; |
92 | namespace ip = boost::asio::ip; |
93 | |
94 | io_service ios; |
95 | ip::tcp::socket sock(ios, ip::tcp::v4()); |
96 | boost::system::error_code ec; |
97 | |
98 | // no_delay class. |
99 | |
100 | ip::tcp::no_delay no_delay1(true); |
101 | BOOST_ASIO_CHECK(no_delay1.value()); |
102 | BOOST_ASIO_CHECK(static_cast<bool>(no_delay1)); |
103 | BOOST_ASIO_CHECK(!!no_delay1); |
104 | sock.set_option(option: no_delay1, ec); |
105 | BOOST_ASIO_CHECK(!ec); |
106 | |
107 | ip::tcp::no_delay no_delay2; |
108 | sock.get_option(option&: no_delay2, ec); |
109 | BOOST_ASIO_CHECK(!ec); |
110 | BOOST_ASIO_CHECK(no_delay2.value()); |
111 | BOOST_ASIO_CHECK(static_cast<bool>(no_delay2)); |
112 | BOOST_ASIO_CHECK(!!no_delay2); |
113 | |
114 | ip::tcp::no_delay no_delay3(false); |
115 | BOOST_ASIO_CHECK(!no_delay3.value()); |
116 | BOOST_ASIO_CHECK(!static_cast<bool>(no_delay3)); |
117 | BOOST_ASIO_CHECK(!no_delay3); |
118 | sock.set_option(option: no_delay3, ec); |
119 | BOOST_ASIO_CHECK(!ec); |
120 | |
121 | ip::tcp::no_delay no_delay4; |
122 | sock.get_option(option&: no_delay4, ec); |
123 | BOOST_ASIO_CHECK(!ec); |
124 | BOOST_ASIO_CHECK(!no_delay4.value()); |
125 | BOOST_ASIO_CHECK(!static_cast<bool>(no_delay4)); |
126 | BOOST_ASIO_CHECK(!no_delay4); |
127 | } |
128 | |
129 | } // namespace ip_tcp_runtime |
130 | |
131 | //------------------------------------------------------------------------------ |
132 | |
133 | // ip_tcp_socket_compile test |
134 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~ |
135 | // The following test checks that all public member functions on the class |
136 | // ip::tcp::socket compile and link correctly. Runtime failures are ignored. |
137 | |
138 | namespace ip_tcp_socket_compile { |
139 | |
140 | void connect_handler(const boost::system::error_code&) |
141 | { |
142 | } |
143 | |
144 | void send_handler(const boost::system::error_code&, std::size_t) |
145 | { |
146 | } |
147 | |
148 | void receive_handler(const boost::system::error_code&, std::size_t) |
149 | { |
150 | } |
151 | |
152 | void write_some_handler(const boost::system::error_code&, std::size_t) |
153 | { |
154 | } |
155 | |
156 | void read_some_handler(const boost::system::error_code&, std::size_t) |
157 | { |
158 | } |
159 | |
160 | void test() |
161 | { |
162 | #if defined(BOOST_ASIO_HAS_BOOST_ARRAY) |
163 | using boost::array; |
164 | #else // defined(BOOST_ASIO_HAS_BOOST_ARRAY) |
165 | using std::array; |
166 | #endif // defined(BOOST_ASIO_HAS_BOOST_ARRAY) |
167 | |
168 | using namespace boost::asio; |
169 | namespace ip = boost::asio::ip; |
170 | |
171 | try |
172 | { |
173 | io_service ios; |
174 | char mutable_char_buffer[128] = "" ; |
175 | const char const_char_buffer[128] = "" ; |
176 | array<boost::asio::mutable_buffer, 2> mutable_buffers = {.elems: { |
177 | boost::asio::buffer(data&: mutable_char_buffer, max_size_in_bytes: 10), |
178 | boost::asio::buffer(data: mutable_char_buffer + 10, size_in_bytes: 10) }}; |
179 | array<boost::asio::const_buffer, 2> const_buffers = {.elems: { |
180 | boost::asio::buffer(data: const_char_buffer, max_size_in_bytes: 10), |
181 | boost::asio::buffer(data: const_char_buffer + 10, size_in_bytes: 10) }}; |
182 | socket_base::message_flags in_flags = 0; |
183 | archetypes::settable_socket_option<void> settable_socket_option1; |
184 | archetypes::settable_socket_option<int> settable_socket_option2; |
185 | archetypes::settable_socket_option<double> settable_socket_option3; |
186 | archetypes::gettable_socket_option<void> gettable_socket_option1; |
187 | archetypes::gettable_socket_option<int> gettable_socket_option2; |
188 | archetypes::gettable_socket_option<double> gettable_socket_option3; |
189 | archetypes::io_control_command io_control_command; |
190 | archetypes::lazy_handler lazy; |
191 | boost::system::error_code ec; |
192 | |
193 | // basic_stream_socket constructors. |
194 | |
195 | ip::tcp::socket socket1(ios); |
196 | ip::tcp::socket socket2(ios, ip::tcp::v4()); |
197 | ip::tcp::socket socket3(ios, ip::tcp::v6()); |
198 | ip::tcp::socket socket4(ios, ip::tcp::endpoint(ip::tcp::v4(), 0)); |
199 | ip::tcp::socket socket5(ios, ip::tcp::endpoint(ip::tcp::v6(), 0)); |
200 | #if !defined(BOOST_ASIO_WINDOWS_RUNTIME) |
201 | ip::tcp::socket::native_handle_type native_socket1 |
202 | = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); |
203 | ip::tcp::socket socket6(ios, ip::tcp::v4(), native_socket1); |
204 | #endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME) |
205 | |
206 | #if defined(BOOST_ASIO_HAS_MOVE) |
207 | ip::tcp::socket socket7(std::move(socket5)); |
208 | #endif // defined(BOOST_ASIO_HAS_MOVE) |
209 | |
210 | // basic_stream_socket operators. |
211 | |
212 | #if defined(BOOST_ASIO_HAS_MOVE) |
213 | socket1 = ip::tcp::socket(ios); |
214 | socket1 = std::move(socket2); |
215 | #endif // defined(BOOST_ASIO_HAS_MOVE) |
216 | |
217 | // basic_io_object functions. |
218 | |
219 | io_service& ios_ref = socket1.get_io_service(); |
220 | (void)ios_ref; |
221 | |
222 | // basic_socket functions. |
223 | |
224 | ip::tcp::socket::lowest_layer_type& lowest_layer = socket1.lowest_layer(); |
225 | (void)lowest_layer; |
226 | |
227 | const ip::tcp::socket& socket8 = socket1; |
228 | const ip::tcp::socket::lowest_layer_type& lowest_layer2 |
229 | = socket8.lowest_layer(); |
230 | (void)lowest_layer2; |
231 | |
232 | socket1.open(protocol: ip::tcp::v4()); |
233 | socket1.open(protocol: ip::tcp::v6()); |
234 | socket1.open(protocol: ip::tcp::v4(), ec); |
235 | socket1.open(protocol: ip::tcp::v6(), ec); |
236 | |
237 | #if !defined(BOOST_ASIO_WINDOWS_RUNTIME) |
238 | ip::tcp::socket::native_handle_type native_socket2 |
239 | = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); |
240 | socket1.assign(protocol: ip::tcp::v4(), native_socket: native_socket2); |
241 | ip::tcp::socket::native_handle_type native_socket3 |
242 | = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); |
243 | socket1.assign(protocol: ip::tcp::v4(), native_socket: native_socket3, ec); |
244 | #endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME) |
245 | |
246 | bool is_open = socket1.is_open(); |
247 | (void)is_open; |
248 | |
249 | socket1.close(); |
250 | socket1.close(ec); |
251 | |
252 | ip::tcp::socket::native_type native_socket4 = socket1.native(); |
253 | (void)native_socket4; |
254 | |
255 | ip::tcp::socket::native_handle_type native_socket5 |
256 | = socket1.native_handle(); |
257 | (void)native_socket5; |
258 | |
259 | socket1.cancel(); |
260 | socket1.cancel(ec); |
261 | |
262 | bool at_mark1 = socket1.at_mark(); |
263 | (void)at_mark1; |
264 | bool at_mark2 = socket1.at_mark(ec); |
265 | (void)at_mark2; |
266 | |
267 | std::size_t available1 = socket1.available(); |
268 | (void)available1; |
269 | std::size_t available2 = socket1.available(ec); |
270 | (void)available2; |
271 | |
272 | socket1.bind(endpoint: ip::tcp::endpoint(ip::tcp::v4(), 0)); |
273 | socket1.bind(endpoint: ip::tcp::endpoint(ip::tcp::v6(), 0)); |
274 | socket1.bind(endpoint: ip::tcp::endpoint(ip::tcp::v4(), 0), ec); |
275 | socket1.bind(endpoint: ip::tcp::endpoint(ip::tcp::v6(), 0), ec); |
276 | |
277 | socket1.connect(peer_endpoint: ip::tcp::endpoint(ip::tcp::v4(), 0)); |
278 | socket1.connect(peer_endpoint: ip::tcp::endpoint(ip::tcp::v6(), 0)); |
279 | socket1.connect(peer_endpoint: ip::tcp::endpoint(ip::tcp::v4(), 0), ec); |
280 | socket1.connect(peer_endpoint: ip::tcp::endpoint(ip::tcp::v6(), 0), ec); |
281 | |
282 | socket1.async_connect(peer_endpoint: ip::tcp::endpoint(ip::tcp::v4(), 0), |
283 | handler: &connect_handler); |
284 | socket1.async_connect(peer_endpoint: ip::tcp::endpoint(ip::tcp::v6(), 0), |
285 | handler: &connect_handler); |
286 | int i1 = socket1.async_connect(peer_endpoint: ip::tcp::endpoint(ip::tcp::v4(), 0), handler&: lazy); |
287 | (void)i1; |
288 | int i2 = socket1.async_connect(peer_endpoint: ip::tcp::endpoint(ip::tcp::v6(), 0), handler&: lazy); |
289 | (void)i2; |
290 | |
291 | socket1.set_option(settable_socket_option1); |
292 | socket1.set_option(option: settable_socket_option1, ec); |
293 | socket1.set_option(settable_socket_option2); |
294 | socket1.set_option(option: settable_socket_option2, ec); |
295 | socket1.set_option(settable_socket_option3); |
296 | socket1.set_option(option: settable_socket_option3, ec); |
297 | |
298 | socket1.get_option(option&: gettable_socket_option1); |
299 | socket1.get_option(option&: gettable_socket_option1, ec); |
300 | socket1.get_option(option&: gettable_socket_option2); |
301 | socket1.get_option(option&: gettable_socket_option2, ec); |
302 | socket1.get_option(option&: gettable_socket_option3); |
303 | socket1.get_option(option&: gettable_socket_option3, ec); |
304 | |
305 | socket1.io_control(command&: io_control_command); |
306 | socket1.io_control(command&: io_control_command, ec); |
307 | |
308 | bool non_blocking1 = socket1.non_blocking(); |
309 | (void)non_blocking1; |
310 | socket1.non_blocking(mode: true); |
311 | socket1.non_blocking(mode: false, ec); |
312 | |
313 | bool non_blocking2 = socket1.native_non_blocking(); |
314 | (void)non_blocking2; |
315 | socket1.native_non_blocking(mode: true); |
316 | socket1.native_non_blocking(mode: false, ec); |
317 | |
318 | ip::tcp::endpoint endpoint1 = socket1.local_endpoint(); |
319 | ip::tcp::endpoint endpoint2 = socket1.local_endpoint(ec); |
320 | |
321 | ip::tcp::endpoint endpoint3 = socket1.remote_endpoint(); |
322 | ip::tcp::endpoint endpoint4 = socket1.remote_endpoint(ec); |
323 | |
324 | socket1.shutdown(what: socket_base::shutdown_both); |
325 | socket1.shutdown(what: socket_base::shutdown_both, ec); |
326 | |
327 | // basic_stream_socket functions. |
328 | |
329 | socket1.send(buffers: buffer(data&: mutable_char_buffer)); |
330 | socket1.send(buffers: buffer(data: const_char_buffer)); |
331 | socket1.send(buffers: mutable_buffers); |
332 | socket1.send(buffers: const_buffers); |
333 | socket1.send(buffers: null_buffers()); |
334 | socket1.send(buffers: buffer(data&: mutable_char_buffer), flags: in_flags); |
335 | socket1.send(buffers: buffer(data: const_char_buffer), flags: in_flags); |
336 | socket1.send(buffers: mutable_buffers, flags: in_flags); |
337 | socket1.send(buffers: const_buffers, flags: in_flags); |
338 | socket1.send(buffers: null_buffers(), flags: in_flags); |
339 | socket1.send(buffers: buffer(data&: mutable_char_buffer), flags: in_flags, ec); |
340 | socket1.send(buffers: buffer(data: const_char_buffer), flags: in_flags, ec); |
341 | socket1.send(buffers: mutable_buffers, flags: in_flags, ec); |
342 | socket1.send(buffers: const_buffers, flags: in_flags, ec); |
343 | socket1.send(buffers: null_buffers(), flags: in_flags, ec); |
344 | |
345 | socket1.async_send(buffers: buffer(data&: mutable_char_buffer), handler: &send_handler); |
346 | socket1.async_send(buffers: buffer(data: const_char_buffer), handler: &send_handler); |
347 | socket1.async_send(buffers: mutable_buffers, handler: &send_handler); |
348 | socket1.async_send(buffers: const_buffers, handler: &send_handler); |
349 | socket1.async_send(buffers: null_buffers(), handler: &send_handler); |
350 | socket1.async_send(buffers: buffer(data&: mutable_char_buffer), flags: in_flags, handler: &send_handler); |
351 | socket1.async_send(buffers: buffer(data: const_char_buffer), flags: in_flags, handler: &send_handler); |
352 | socket1.async_send(buffers: mutable_buffers, flags: in_flags, handler: &send_handler); |
353 | socket1.async_send(buffers: const_buffers, flags: in_flags, handler: &send_handler); |
354 | socket1.async_send(buffers: null_buffers(), flags: in_flags, handler: &send_handler); |
355 | int i3 = socket1.async_send(buffers: buffer(data&: mutable_char_buffer), handler&: lazy); |
356 | (void)i3; |
357 | int i4 = socket1.async_send(buffers: buffer(data: const_char_buffer), handler&: lazy); |
358 | (void)i4; |
359 | int i5 = socket1.async_send(buffers: mutable_buffers, handler&: lazy); |
360 | (void)i5; |
361 | int i6 = socket1.async_send(buffers: const_buffers, handler&: lazy); |
362 | (void)i6; |
363 | int i7 = socket1.async_send(buffers: null_buffers(), handler&: lazy); |
364 | (void)i7; |
365 | int i8 = socket1.async_send(buffers: buffer(data&: mutable_char_buffer), flags: in_flags, handler&: lazy); |
366 | (void)i8; |
367 | int i9 = socket1.async_send(buffers: buffer(data: const_char_buffer), flags: in_flags, handler&: lazy); |
368 | (void)i9; |
369 | int i10 = socket1.async_send(buffers: mutable_buffers, flags: in_flags, handler&: lazy); |
370 | (void)i10; |
371 | int i11 = socket1.async_send(buffers: const_buffers, flags: in_flags, handler&: lazy); |
372 | (void)i11; |
373 | int i12 = socket1.async_send(buffers: null_buffers(), flags: in_flags, handler&: lazy); |
374 | (void)i12; |
375 | |
376 | socket1.receive(buffers: buffer(data&: mutable_char_buffer)); |
377 | socket1.receive(buffers: mutable_buffers); |
378 | socket1.receive(buffers: null_buffers()); |
379 | socket1.receive(buffers: buffer(data&: mutable_char_buffer), flags: in_flags); |
380 | socket1.receive(buffers: mutable_buffers, flags: in_flags); |
381 | socket1.receive(buffers: null_buffers(), flags: in_flags); |
382 | socket1.receive(buffers: buffer(data&: mutable_char_buffer), flags: in_flags, ec); |
383 | socket1.receive(buffers: mutable_buffers, flags: in_flags, ec); |
384 | socket1.receive(buffers: null_buffers(), flags: in_flags, ec); |
385 | |
386 | socket1.async_receive(buffers: buffer(data&: mutable_char_buffer), handler: &receive_handler); |
387 | socket1.async_receive(buffers: mutable_buffers, handler: &receive_handler); |
388 | socket1.async_receive(buffers: null_buffers(), handler: &receive_handler); |
389 | socket1.async_receive(buffers: buffer(data&: mutable_char_buffer), flags: in_flags, |
390 | handler: &receive_handler); |
391 | socket1.async_receive(buffers: mutable_buffers, flags: in_flags, handler: &receive_handler); |
392 | socket1.async_receive(buffers: null_buffers(), flags: in_flags, handler: &receive_handler); |
393 | int i13 = socket1.async_receive(buffers: buffer(data&: mutable_char_buffer), handler&: lazy); |
394 | (void)i13; |
395 | int i14 = socket1.async_receive(buffers: mutable_buffers, handler&: lazy); |
396 | (void)i14; |
397 | int i15 = socket1.async_receive(buffers: null_buffers(), handler&: lazy); |
398 | (void)i15; |
399 | int i16 = socket1.async_receive(buffers: buffer(data&: mutable_char_buffer), flags: in_flags, |
400 | handler&: lazy); |
401 | (void)i16; |
402 | int i17 = socket1.async_receive(buffers: mutable_buffers, flags: in_flags, handler&: lazy); |
403 | (void)i17; |
404 | int i18 = socket1.async_receive(buffers: null_buffers(), flags: in_flags, handler&: lazy); |
405 | (void)i18; |
406 | |
407 | socket1.write_some(buffers: buffer(data&: mutable_char_buffer)); |
408 | socket1.write_some(buffers: buffer(data: const_char_buffer)); |
409 | socket1.write_some(buffers: mutable_buffers); |
410 | socket1.write_some(buffers: const_buffers); |
411 | socket1.write_some(buffers: null_buffers()); |
412 | socket1.write_some(buffers: buffer(data&: mutable_char_buffer), ec); |
413 | socket1.write_some(buffers: buffer(data: const_char_buffer), ec); |
414 | socket1.write_some(buffers: mutable_buffers, ec); |
415 | socket1.write_some(buffers: const_buffers, ec); |
416 | socket1.write_some(buffers: null_buffers(), ec); |
417 | |
418 | socket1.async_write_some(buffers: buffer(data&: mutable_char_buffer), handler: &write_some_handler); |
419 | socket1.async_write_some(buffers: buffer(data: const_char_buffer), handler: &write_some_handler); |
420 | socket1.async_write_some(buffers: mutable_buffers, handler: &write_some_handler); |
421 | socket1.async_write_some(buffers: const_buffers, handler: &write_some_handler); |
422 | socket1.async_write_some(buffers: null_buffers(), handler: &write_some_handler); |
423 | int i19 = socket1.async_write_some(buffers: buffer(data&: mutable_char_buffer), handler&: lazy); |
424 | (void)i19; |
425 | int i20 = socket1.async_write_some(buffers: buffer(data: const_char_buffer), handler&: lazy); |
426 | (void)i20; |
427 | int i21 = socket1.async_write_some(buffers: mutable_buffers, handler&: lazy); |
428 | (void)i21; |
429 | int i22 = socket1.async_write_some(buffers: const_buffers, handler&: lazy); |
430 | (void)i22; |
431 | int i23 = socket1.async_write_some(buffers: null_buffers(), handler&: lazy); |
432 | (void)i23; |
433 | |
434 | socket1.read_some(buffers: buffer(data&: mutable_char_buffer)); |
435 | socket1.read_some(buffers: mutable_buffers); |
436 | socket1.read_some(buffers: null_buffers()); |
437 | socket1.read_some(buffers: buffer(data&: mutable_char_buffer), ec); |
438 | socket1.read_some(buffers: mutable_buffers, ec); |
439 | socket1.read_some(buffers: null_buffers(), ec); |
440 | |
441 | socket1.async_read_some(buffers: buffer(data&: mutable_char_buffer), handler: &read_some_handler); |
442 | socket1.async_read_some(buffers: mutable_buffers, handler: &read_some_handler); |
443 | socket1.async_read_some(buffers: null_buffers(), handler: &read_some_handler); |
444 | int i24 = socket1.async_read_some(buffers: buffer(data&: mutable_char_buffer), handler&: lazy); |
445 | (void)i24; |
446 | int i25 = socket1.async_read_some(buffers: mutable_buffers, handler&: lazy); |
447 | (void)i25; |
448 | int i26 = socket1.async_read_some(buffers: null_buffers(), handler&: lazy); |
449 | (void)i26; |
450 | } |
451 | catch (std::exception&) |
452 | { |
453 | } |
454 | } |
455 | |
456 | } // namespace ip_tcp_socket_compile |
457 | |
458 | //------------------------------------------------------------------------------ |
459 | |
460 | // ip_tcp_socket_runtime test |
461 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~ |
462 | // The following test checks the runtime operation of the ip::tcp::socket class. |
463 | |
464 | namespace ip_tcp_socket_runtime { |
465 | |
466 | static const char write_data[] |
467 | = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" ; |
468 | |
469 | void handle_read_noop(const boost::system::error_code& err, |
470 | size_t bytes_transferred, bool* called) |
471 | { |
472 | *called = true; |
473 | BOOST_ASIO_CHECK(!err); |
474 | BOOST_ASIO_CHECK(bytes_transferred == 0); |
475 | } |
476 | |
477 | void handle_write_noop(const boost::system::error_code& err, |
478 | size_t bytes_transferred, bool* called) |
479 | { |
480 | *called = true; |
481 | BOOST_ASIO_CHECK(!err); |
482 | BOOST_ASIO_CHECK(bytes_transferred == 0); |
483 | } |
484 | |
485 | void handle_read(const boost::system::error_code& err, |
486 | size_t bytes_transferred, bool* called) |
487 | { |
488 | *called = true; |
489 | BOOST_ASIO_CHECK(!err); |
490 | BOOST_ASIO_CHECK(bytes_transferred == sizeof(write_data)); |
491 | } |
492 | |
493 | void handle_write(const boost::system::error_code& err, |
494 | size_t bytes_transferred, bool* called) |
495 | { |
496 | *called = true; |
497 | BOOST_ASIO_CHECK(!err); |
498 | BOOST_ASIO_CHECK(bytes_transferred == sizeof(write_data)); |
499 | } |
500 | |
501 | void handle_read_cancel(const boost::system::error_code& err, |
502 | size_t bytes_transferred, bool* called) |
503 | { |
504 | *called = true; |
505 | BOOST_ASIO_CHECK(err == boost::asio::error::operation_aborted); |
506 | BOOST_ASIO_CHECK(bytes_transferred == 0); |
507 | } |
508 | |
509 | void handle_read_eof(const boost::system::error_code& err, |
510 | size_t bytes_transferred, bool* called) |
511 | { |
512 | *called = true; |
513 | BOOST_ASIO_CHECK(err == boost::asio::error::eof); |
514 | BOOST_ASIO_CHECK(bytes_transferred == 0); |
515 | } |
516 | |
517 | void test() |
518 | { |
519 | using namespace std; // For memcmp. |
520 | using namespace boost::asio; |
521 | namespace ip = boost::asio::ip; |
522 | |
523 | #if defined(BOOST_ASIO_HAS_BOOST_BIND) |
524 | namespace bindns = boost; |
525 | #else // defined(BOOST_ASIO_HAS_BOOST_BIND) |
526 | namespace bindns = std; |
527 | using std::placeholders::_1; |
528 | using std::placeholders::_2; |
529 | #endif // defined(BOOST_ASIO_HAS_BOOST_BIND) |
530 | |
531 | io_service ios; |
532 | |
533 | ip::tcp::acceptor acceptor(ios, ip::tcp::endpoint(ip::tcp::v4(), 0)); |
534 | ip::tcp::endpoint server_endpoint = acceptor.local_endpoint(); |
535 | server_endpoint.address(addr: ip::address_v4::loopback()); |
536 | |
537 | ip::tcp::socket client_side_socket(ios); |
538 | ip::tcp::socket server_side_socket(ios); |
539 | |
540 | client_side_socket.connect(peer_endpoint: server_endpoint); |
541 | acceptor.accept(peer&: server_side_socket); |
542 | |
543 | // No-op read. |
544 | |
545 | bool read_noop_completed = false; |
546 | client_side_socket.async_read_some( |
547 | buffers: boost::asio::mutable_buffers_1(0, 0), |
548 | handler: bindns::bind(f: handle_read_noop, |
549 | a1: _1, a2: _2, a3: &read_noop_completed)); |
550 | |
551 | ios.run(); |
552 | BOOST_ASIO_CHECK(read_noop_completed); |
553 | |
554 | // No-op write. |
555 | |
556 | bool write_noop_completed = false; |
557 | client_side_socket.async_write_some( |
558 | buffers: boost::asio::const_buffers_1(0, 0), |
559 | handler: bindns::bind(f: handle_write_noop, |
560 | a1: _1, a2: _2, a3: &write_noop_completed)); |
561 | |
562 | ios.reset(); |
563 | ios.run(); |
564 | BOOST_ASIO_CHECK(write_noop_completed); |
565 | |
566 | // Read and write to transfer data. |
567 | |
568 | char read_buffer[sizeof(write_data)]; |
569 | bool read_completed = false; |
570 | boost::asio::async_read(s&: client_side_socket, |
571 | buffers: boost::asio::buffer(data&: read_buffer), |
572 | handler: bindns::bind(f: handle_read, |
573 | a1: _1, a2: _2, a3: &read_completed)); |
574 | |
575 | bool write_completed = false; |
576 | boost::asio::async_write(s&: server_side_socket, |
577 | buffers: boost::asio::buffer(data: write_data), |
578 | handler: bindns::bind(f: handle_write, |
579 | a1: _1, a2: _2, a3: &write_completed)); |
580 | |
581 | ios.reset(); |
582 | ios.run(); |
583 | BOOST_ASIO_CHECK(read_completed); |
584 | BOOST_ASIO_CHECK(write_completed); |
585 | BOOST_ASIO_CHECK(memcmp(read_buffer, write_data, sizeof(write_data)) == 0); |
586 | |
587 | // Cancelled read. |
588 | |
589 | bool read_cancel_completed = false; |
590 | boost::asio::async_read(s&: server_side_socket, |
591 | buffers: boost::asio::buffer(data&: read_buffer), |
592 | handler: bindns::bind(f: handle_read_cancel, |
593 | a1: _1, a2: _2, a3: &read_cancel_completed)); |
594 | |
595 | ios.reset(); |
596 | ios.poll(); |
597 | BOOST_ASIO_CHECK(!read_cancel_completed); |
598 | |
599 | server_side_socket.cancel(); |
600 | |
601 | ios.reset(); |
602 | ios.run(); |
603 | BOOST_ASIO_CHECK(read_cancel_completed); |
604 | |
605 | // A read when the peer closes socket should fail with eof. |
606 | |
607 | bool read_eof_completed = false; |
608 | boost::asio::async_read(s&: client_side_socket, |
609 | buffers: boost::asio::buffer(data&: read_buffer), |
610 | handler: bindns::bind(f: handle_read_eof, |
611 | a1: _1, a2: _2, a3: &read_eof_completed)); |
612 | |
613 | server_side_socket.close(); |
614 | |
615 | ios.reset(); |
616 | ios.run(); |
617 | BOOST_ASIO_CHECK(read_eof_completed); |
618 | } |
619 | |
620 | } // namespace ip_tcp_socket_runtime |
621 | |
622 | //------------------------------------------------------------------------------ |
623 | |
624 | // ip_tcp_acceptor_compile test |
625 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
626 | // The following test checks that all public member functions on the class |
627 | // ip::tcp::acceptor compile and link correctly. Runtime failures are ignored. |
628 | |
629 | namespace ip_tcp_acceptor_compile { |
630 | |
631 | void accept_handler(const boost::system::error_code&) |
632 | { |
633 | } |
634 | |
635 | void test() |
636 | { |
637 | using namespace boost::asio; |
638 | namespace ip = boost::asio::ip; |
639 | |
640 | try |
641 | { |
642 | io_service ios; |
643 | ip::tcp::socket peer_socket(ios); |
644 | ip::tcp::endpoint peer_endpoint; |
645 | archetypes::settable_socket_option<void> settable_socket_option1; |
646 | archetypes::settable_socket_option<int> settable_socket_option2; |
647 | archetypes::settable_socket_option<double> settable_socket_option3; |
648 | archetypes::gettable_socket_option<void> gettable_socket_option1; |
649 | archetypes::gettable_socket_option<int> gettable_socket_option2; |
650 | archetypes::gettable_socket_option<double> gettable_socket_option3; |
651 | archetypes::io_control_command io_control_command; |
652 | archetypes::lazy_handler lazy; |
653 | boost::system::error_code ec; |
654 | |
655 | // basic_socket_acceptor constructors. |
656 | |
657 | ip::tcp::acceptor acceptor1(ios); |
658 | ip::tcp::acceptor acceptor2(ios, ip::tcp::v4()); |
659 | ip::tcp::acceptor acceptor3(ios, ip::tcp::v6()); |
660 | ip::tcp::acceptor acceptor4(ios, ip::tcp::endpoint(ip::tcp::v4(), 0)); |
661 | ip::tcp::acceptor acceptor5(ios, ip::tcp::endpoint(ip::tcp::v6(), 0)); |
662 | #if !defined(BOOST_ASIO_WINDOWS_RUNTIME) |
663 | ip::tcp::acceptor::native_handle_type native_acceptor1 |
664 | = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); |
665 | ip::tcp::acceptor acceptor6(ios, ip::tcp::v4(), native_acceptor1); |
666 | #endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME) |
667 | |
668 | #if defined(BOOST_ASIO_HAS_MOVE) |
669 | ip::tcp::acceptor acceptor7(std::move(acceptor5)); |
670 | #endif // defined(BOOST_ASIO_HAS_MOVE) |
671 | |
672 | // basic_socket_acceptor operators. |
673 | |
674 | #if defined(BOOST_ASIO_HAS_MOVE) |
675 | acceptor1 = ip::tcp::acceptor(ios); |
676 | acceptor1 = std::move(acceptor2); |
677 | #endif // defined(BOOST_ASIO_HAS_MOVE) |
678 | |
679 | // basic_io_object functions. |
680 | |
681 | io_service& ios_ref = acceptor1.get_io_service(); |
682 | (void)ios_ref; |
683 | |
684 | // basic_socket_acceptor functions. |
685 | |
686 | acceptor1.open(protocol: ip::tcp::v4()); |
687 | acceptor1.open(protocol: ip::tcp::v6()); |
688 | acceptor1.open(protocol: ip::tcp::v4(), ec); |
689 | acceptor1.open(protocol: ip::tcp::v6(), ec); |
690 | |
691 | #if !defined(BOOST_ASIO_WINDOWS_RUNTIME) |
692 | ip::tcp::acceptor::native_handle_type native_acceptor2 |
693 | = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); |
694 | acceptor1.assign(protocol: ip::tcp::v4(), native_acceptor: native_acceptor2); |
695 | ip::tcp::acceptor::native_handle_type native_acceptor3 |
696 | = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); |
697 | acceptor1.assign(protocol: ip::tcp::v4(), native_acceptor: native_acceptor3, ec); |
698 | #endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME) |
699 | |
700 | bool is_open = acceptor1.is_open(); |
701 | (void)is_open; |
702 | |
703 | acceptor1.close(); |
704 | acceptor1.close(ec); |
705 | |
706 | ip::tcp::acceptor::native_type native_acceptor4 = acceptor1.native(); |
707 | (void)native_acceptor4; |
708 | |
709 | ip::tcp::acceptor::native_handle_type native_acceptor5 |
710 | = acceptor1.native_handle(); |
711 | (void)native_acceptor5; |
712 | |
713 | acceptor1.cancel(); |
714 | acceptor1.cancel(ec); |
715 | |
716 | acceptor1.bind(endpoint: ip::tcp::endpoint(ip::tcp::v4(), 0)); |
717 | acceptor1.bind(endpoint: ip::tcp::endpoint(ip::tcp::v6(), 0)); |
718 | acceptor1.bind(endpoint: ip::tcp::endpoint(ip::tcp::v4(), 0), ec); |
719 | acceptor1.bind(endpoint: ip::tcp::endpoint(ip::tcp::v6(), 0), ec); |
720 | |
721 | acceptor1.set_option(settable_socket_option1); |
722 | acceptor1.set_option(option: settable_socket_option1, ec); |
723 | acceptor1.set_option(settable_socket_option2); |
724 | acceptor1.set_option(option: settable_socket_option2, ec); |
725 | acceptor1.set_option(settable_socket_option3); |
726 | acceptor1.set_option(option: settable_socket_option3, ec); |
727 | |
728 | acceptor1.get_option(option&: gettable_socket_option1); |
729 | acceptor1.get_option(option&: gettable_socket_option1, ec); |
730 | acceptor1.get_option(option&: gettable_socket_option2); |
731 | acceptor1.get_option(option&: gettable_socket_option2, ec); |
732 | acceptor1.get_option(option&: gettable_socket_option3); |
733 | acceptor1.get_option(option&: gettable_socket_option3, ec); |
734 | |
735 | acceptor1.io_control(command&: io_control_command); |
736 | acceptor1.io_control(command&: io_control_command, ec); |
737 | |
738 | bool non_blocking1 = acceptor1.non_blocking(); |
739 | (void)non_blocking1; |
740 | acceptor1.non_blocking(mode: true); |
741 | acceptor1.non_blocking(mode: false, ec); |
742 | |
743 | bool non_blocking2 = acceptor1.native_non_blocking(); |
744 | (void)non_blocking2; |
745 | acceptor1.native_non_blocking(mode: true); |
746 | acceptor1.native_non_blocking(mode: false, ec); |
747 | |
748 | ip::tcp::endpoint endpoint1 = acceptor1.local_endpoint(); |
749 | ip::tcp::endpoint endpoint2 = acceptor1.local_endpoint(ec); |
750 | |
751 | acceptor1.accept(peer&: peer_socket); |
752 | acceptor1.accept(peer&: peer_socket, ec); |
753 | acceptor1.accept(peer&: peer_socket, peer_endpoint); |
754 | acceptor1.accept(peer&: peer_socket, peer_endpoint, ec); |
755 | |
756 | acceptor1.async_accept(peer&: peer_socket, handler: &accept_handler); |
757 | acceptor1.async_accept(peer&: peer_socket, peer_endpoint, handler: &accept_handler); |
758 | int i1 = acceptor1.async_accept(peer&: peer_socket, handler&: lazy); |
759 | (void)i1; |
760 | int i2 = acceptor1.async_accept(peer&: peer_socket, peer_endpoint, handler&: lazy); |
761 | (void)i2; |
762 | } |
763 | catch (std::exception&) |
764 | { |
765 | } |
766 | } |
767 | |
768 | } // namespace ip_tcp_acceptor_compile |
769 | |
770 | //------------------------------------------------------------------------------ |
771 | |
772 | // ip_tcp_acceptor_runtime test |
773 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
774 | // The following test checks the runtime operation of the ip::tcp::acceptor |
775 | // class. |
776 | |
777 | namespace ip_tcp_acceptor_runtime { |
778 | |
779 | void handle_accept(const boost::system::error_code& err) |
780 | { |
781 | BOOST_ASIO_CHECK(!err); |
782 | } |
783 | |
784 | void handle_connect(const boost::system::error_code& err) |
785 | { |
786 | BOOST_ASIO_CHECK(!err); |
787 | } |
788 | |
789 | void test() |
790 | { |
791 | using namespace boost::asio; |
792 | namespace ip = boost::asio::ip; |
793 | |
794 | io_service ios; |
795 | |
796 | ip::tcp::acceptor acceptor(ios, ip::tcp::endpoint(ip::tcp::v4(), 0)); |
797 | ip::tcp::endpoint server_endpoint = acceptor.local_endpoint(); |
798 | server_endpoint.address(addr: ip::address_v4::loopback()); |
799 | |
800 | ip::tcp::socket client_side_socket(ios); |
801 | ip::tcp::socket server_side_socket(ios); |
802 | |
803 | client_side_socket.connect(peer_endpoint: server_endpoint); |
804 | acceptor.accept(peer&: server_side_socket); |
805 | |
806 | client_side_socket.close(); |
807 | server_side_socket.close(); |
808 | |
809 | client_side_socket.connect(peer_endpoint: server_endpoint); |
810 | ip::tcp::endpoint client_endpoint; |
811 | acceptor.accept(peer&: server_side_socket, peer_endpoint&: client_endpoint); |
812 | |
813 | ip::tcp::acceptor::non_blocking_io command(false); |
814 | acceptor.io_control(command); |
815 | |
816 | ip::tcp::endpoint client_side_local_endpoint |
817 | = client_side_socket.local_endpoint(); |
818 | BOOST_ASIO_CHECK(client_side_local_endpoint.port() == client_endpoint.port()); |
819 | |
820 | ip::tcp::endpoint server_side_remote_endpoint |
821 | = server_side_socket.remote_endpoint(); |
822 | BOOST_ASIO_CHECK(server_side_remote_endpoint.port() |
823 | == client_endpoint.port()); |
824 | |
825 | client_side_socket.close(); |
826 | server_side_socket.close(); |
827 | |
828 | acceptor.async_accept(peer&: server_side_socket, handler: &handle_accept); |
829 | client_side_socket.async_connect(peer_endpoint: server_endpoint, handler: &handle_connect); |
830 | |
831 | ios.run(); |
832 | |
833 | client_side_socket.close(); |
834 | server_side_socket.close(); |
835 | |
836 | acceptor.async_accept(peer&: server_side_socket, peer_endpoint&: client_endpoint, handler: &handle_accept); |
837 | client_side_socket.async_connect(peer_endpoint: server_endpoint, handler: &handle_connect); |
838 | |
839 | ios.reset(); |
840 | ios.run(); |
841 | |
842 | client_side_local_endpoint = client_side_socket.local_endpoint(); |
843 | BOOST_ASIO_CHECK(client_side_local_endpoint.port() == client_endpoint.port()); |
844 | |
845 | server_side_remote_endpoint = server_side_socket.remote_endpoint(); |
846 | BOOST_ASIO_CHECK(server_side_remote_endpoint.port() |
847 | == client_endpoint.port()); |
848 | } |
849 | |
850 | } // namespace ip_tcp_acceptor_runtime |
851 | |
852 | //------------------------------------------------------------------------------ |
853 | |
854 | // ip_tcp_resolver_compile test |
855 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
856 | // The following test checks that all public member functions on the class |
857 | // ip::tcp::resolver compile and link correctly. Runtime failures are ignored. |
858 | |
859 | namespace ip_tcp_resolver_compile { |
860 | |
861 | void resolve_handler(const boost::system::error_code&, |
862 | boost::asio::ip::tcp::resolver::iterator) |
863 | { |
864 | } |
865 | |
866 | void test() |
867 | { |
868 | using namespace boost::asio; |
869 | namespace ip = boost::asio::ip; |
870 | |
871 | try |
872 | { |
873 | io_service ios; |
874 | archetypes::lazy_handler lazy; |
875 | boost::system::error_code ec; |
876 | ip::tcp::resolver::query q(ip::tcp::v4(), "localhost" , "0" ); |
877 | ip::tcp::endpoint e(ip::address_v4::loopback(), 0); |
878 | |
879 | // basic_resolver constructors. |
880 | |
881 | ip::tcp::resolver resolver(ios); |
882 | |
883 | // basic_io_object functions. |
884 | |
885 | io_service& ios_ref = resolver.get_io_service(); |
886 | (void)ios_ref; |
887 | |
888 | // basic_resolver functions. |
889 | |
890 | resolver.cancel(); |
891 | |
892 | ip::tcp::resolver::iterator iter1 = resolver.resolve(q); |
893 | (void)iter1; |
894 | |
895 | ip::tcp::resolver::iterator iter2 = resolver.resolve(q, ec); |
896 | (void)iter2; |
897 | |
898 | ip::tcp::resolver::iterator iter3 = resolver.resolve(e); |
899 | (void)iter3; |
900 | |
901 | ip::tcp::resolver::iterator iter4 = resolver.resolve(e, ec); |
902 | (void)iter4; |
903 | |
904 | resolver.async_resolve(q, handler: &resolve_handler); |
905 | int i1 = resolver.async_resolve(q, handler&: lazy); |
906 | (void)i1; |
907 | |
908 | resolver.async_resolve(e, handler: &resolve_handler); |
909 | int i2 = resolver.async_resolve(e, handler&: lazy); |
910 | (void)i2; |
911 | } |
912 | catch (std::exception&) |
913 | { |
914 | } |
915 | } |
916 | |
917 | } // namespace ip_tcp_resolver_compile |
918 | |
919 | //------------------------------------------------------------------------------ |
920 | |
921 | BOOST_ASIO_TEST_SUITE |
922 | ( |
923 | "ip/tcp" , |
924 | BOOST_ASIO_TEST_CASE(ip_tcp_compile::test) |
925 | BOOST_ASIO_TEST_CASE(ip_tcp_runtime::test) |
926 | BOOST_ASIO_TEST_CASE(ip_tcp_socket_compile::test) |
927 | BOOST_ASIO_TEST_CASE(ip_tcp_socket_runtime::test) |
928 | BOOST_ASIO_TEST_CASE(ip_tcp_acceptor_compile::test) |
929 | BOOST_ASIO_TEST_CASE(ip_tcp_acceptor_runtime::test) |
930 | BOOST_ASIO_TEST_CASE(ip_tcp_resolver_compile::test) |
931 | ) |
932 | |