1 | // |
2 | // tcp.cpp |
3 | // ~~~~~~~ |
4 | // |
5 | // Copyright (c) 2003-2024 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 <functional> |
24 | #include <boost/asio/io_context.hpp> |
25 | #include <boost/asio/read.hpp> |
26 | #include <boost/asio/write.hpp> |
27 | #include "../unit_test.hpp" |
28 | #include "../archetypes/async_result.hpp" |
29 | #include "../archetypes/gettable_socket_option.hpp" |
30 | #include "../archetypes/io_control_command.hpp" |
31 | #include "../archetypes/settable_socket_option.hpp" |
32 | |
33 | #if defined(BOOST_ASIO_HAS_BOOST_ARRAY) |
34 | # include <boost/array.hpp> |
35 | #else // defined(BOOST_ASIO_HAS_BOOST_ARRAY) |
36 | # include <array> |
37 | #endif // defined(BOOST_ASIO_HAS_BOOST_ARRAY) |
38 | |
39 | //------------------------------------------------------------------------------ |
40 | |
41 | // ip_tcp_compile test |
42 | // ~~~~~~~~~~~~~~~~~~~ |
43 | // The following test checks that all nested classes, enums and constants in |
44 | // ip::tcp compile and link correctly. Runtime failures are ignored. |
45 | |
46 | namespace ip_tcp_compile { |
47 | |
48 | void test() |
49 | { |
50 | using namespace boost::asio; |
51 | namespace ip = boost::asio::ip; |
52 | |
53 | try |
54 | { |
55 | io_context ioc; |
56 | ip::tcp::socket sock(ioc); |
57 | |
58 | // no_delay class. |
59 | |
60 | ip::tcp::no_delay no_delay1(true); |
61 | sock.set_option(no_delay1); |
62 | ip::tcp::no_delay no_delay2; |
63 | sock.get_option(option&: no_delay2); |
64 | no_delay1 = true; |
65 | (void)static_cast<bool>(no_delay1); |
66 | (void)static_cast<bool>(!no_delay1); |
67 | (void)static_cast<bool>(no_delay1.value()); |
68 | |
69 | ip::tcp::endpoint ep; |
70 | (void)static_cast<std::size_t>(std::hash<ip::tcp::endpoint>()(ep)); |
71 | } |
72 | catch (std::exception&) |
73 | { |
74 | } |
75 | } |
76 | |
77 | } // namespace ip_tcp_compile |
78 | |
79 | //------------------------------------------------------------------------------ |
80 | |
81 | // ip_tcp_runtime test |
82 | // ~~~~~~~~~~~~~~~~~~~ |
83 | // The following test checks the runtime operation of the ip::tcp class. |
84 | |
85 | namespace ip_tcp_runtime { |
86 | |
87 | void test() |
88 | { |
89 | using namespace boost::asio; |
90 | namespace ip = boost::asio::ip; |
91 | |
92 | io_context ioc; |
93 | ip::tcp::socket sock(ioc, ip::tcp::v4()); |
94 | boost::system::error_code ec; |
95 | |
96 | // no_delay class. |
97 | |
98 | ip::tcp::no_delay no_delay1(true); |
99 | BOOST_ASIO_CHECK(no_delay1.value()); |
100 | BOOST_ASIO_CHECK(static_cast<bool>(no_delay1)); |
101 | BOOST_ASIO_CHECK(!!no_delay1); |
102 | sock.set_option(option: no_delay1, ec); |
103 | BOOST_ASIO_CHECK(!ec); |
104 | |
105 | ip::tcp::no_delay no_delay2; |
106 | sock.get_option(option&: no_delay2, ec); |
107 | BOOST_ASIO_CHECK(!ec); |
108 | BOOST_ASIO_CHECK(no_delay2.value()); |
109 | BOOST_ASIO_CHECK(static_cast<bool>(no_delay2)); |
110 | BOOST_ASIO_CHECK(!!no_delay2); |
111 | |
112 | ip::tcp::no_delay no_delay3(false); |
113 | BOOST_ASIO_CHECK(!no_delay3.value()); |
114 | BOOST_ASIO_CHECK(!static_cast<bool>(no_delay3)); |
115 | BOOST_ASIO_CHECK(!no_delay3); |
116 | sock.set_option(option: no_delay3, ec); |
117 | BOOST_ASIO_CHECK(!ec); |
118 | |
119 | ip::tcp::no_delay no_delay4; |
120 | sock.get_option(option&: no_delay4, ec); |
121 | BOOST_ASIO_CHECK(!ec); |
122 | BOOST_ASIO_CHECK(!no_delay4.value()); |
123 | BOOST_ASIO_CHECK(!static_cast<bool>(no_delay4)); |
124 | BOOST_ASIO_CHECK(!no_delay4); |
125 | } |
126 | |
127 | } // namespace ip_tcp_runtime |
128 | |
129 | //------------------------------------------------------------------------------ |
130 | |
131 | // ip_tcp_socket_compile test |
132 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~ |
133 | // The following test checks that all public member functions on the class |
134 | // ip::tcp::socket compile and link correctly. Runtime failures are ignored. |
135 | |
136 | namespace ip_tcp_socket_compile { |
137 | |
138 | struct connect_handler |
139 | { |
140 | connect_handler() {} |
141 | void operator()(const boost::system::error_code&) {} |
142 | connect_handler(connect_handler&&) {} |
143 | private: |
144 | connect_handler(const connect_handler&); |
145 | }; |
146 | |
147 | struct wait_handler |
148 | { |
149 | wait_handler() {} |
150 | void operator()(const boost::system::error_code&) {} |
151 | wait_handler(wait_handler&&) {} |
152 | private: |
153 | wait_handler(const wait_handler&); |
154 | }; |
155 | |
156 | struct send_handler |
157 | { |
158 | send_handler() {} |
159 | void operator()(const boost::system::error_code&, std::size_t) {} |
160 | send_handler(send_handler&&) {} |
161 | private: |
162 | send_handler(const send_handler&); |
163 | }; |
164 | |
165 | struct receive_handler |
166 | { |
167 | receive_handler() {} |
168 | void operator()(const boost::system::error_code&, std::size_t) {} |
169 | receive_handler(receive_handler&&) {} |
170 | private: |
171 | receive_handler(const receive_handler&); |
172 | }; |
173 | |
174 | struct write_some_handler |
175 | { |
176 | write_some_handler() {} |
177 | void operator()(const boost::system::error_code&, std::size_t) {} |
178 | write_some_handler(write_some_handler&&) {} |
179 | private: |
180 | write_some_handler(const write_some_handler&); |
181 | }; |
182 | |
183 | struct read_some_handler |
184 | { |
185 | read_some_handler() {} |
186 | void operator()(const boost::system::error_code&, std::size_t) {} |
187 | read_some_handler(read_some_handler&&) {} |
188 | private: |
189 | read_some_handler(const read_some_handler&); |
190 | }; |
191 | |
192 | void test() |
193 | { |
194 | #if defined(BOOST_ASIO_HAS_BOOST_ARRAY) |
195 | using boost::array; |
196 | #else // defined(BOOST_ASIO_HAS_BOOST_ARRAY) |
197 | using std::array; |
198 | #endif // defined(BOOST_ASIO_HAS_BOOST_ARRAY) |
199 | |
200 | using namespace boost::asio; |
201 | namespace ip = boost::asio::ip; |
202 | |
203 | try |
204 | { |
205 | io_context ioc; |
206 | const io_context::executor_type ioc_ex = ioc.get_executor(); |
207 | char mutable_char_buffer[128] = "" ; |
208 | const char const_char_buffer[128] = "" ; |
209 | array<boost::asio::mutable_buffer, 2> mutable_buffers = {.elems: { |
210 | boost::asio::buffer(data&: mutable_char_buffer, max_size_in_bytes: 10), |
211 | boost::asio::buffer(data: mutable_char_buffer + 10, size_in_bytes: 10) }}; |
212 | array<boost::asio::const_buffer, 2> const_buffers = {.elems: { |
213 | boost::asio::buffer(data: const_char_buffer, max_size_in_bytes: 10), |
214 | boost::asio::buffer(data: const_char_buffer + 10, size_in_bytes: 10) }}; |
215 | socket_base::message_flags in_flags = 0; |
216 | archetypes::settable_socket_option<void> settable_socket_option1; |
217 | archetypes::settable_socket_option<int> settable_socket_option2; |
218 | archetypes::settable_socket_option<double> settable_socket_option3; |
219 | archetypes::gettable_socket_option<void> gettable_socket_option1; |
220 | archetypes::gettable_socket_option<int> gettable_socket_option2; |
221 | archetypes::gettable_socket_option<double> gettable_socket_option3; |
222 | archetypes::io_control_command io_control_command; |
223 | archetypes::immediate_handler immediate; |
224 | archetypes::lazy_handler lazy; |
225 | boost::system::error_code ec; |
226 | |
227 | // basic_stream_socket constructors. |
228 | |
229 | ip::tcp::socket socket1(ioc); |
230 | ip::tcp::socket socket2(ioc, ip::tcp::v4()); |
231 | ip::tcp::socket socket3(ioc, ip::tcp::v6()); |
232 | ip::tcp::socket socket4(ioc, ip::tcp::endpoint(ip::tcp::v4(), 0)); |
233 | ip::tcp::socket socket5(ioc, ip::tcp::endpoint(ip::tcp::v6(), 0)); |
234 | #if !defined(BOOST_ASIO_WINDOWS_RUNTIME) |
235 | ip::tcp::socket::native_handle_type native_socket1 |
236 | = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); |
237 | ip::tcp::socket socket6(ioc, ip::tcp::v4(), native_socket1); |
238 | #endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME) |
239 | |
240 | ip::tcp::socket socket7(ioc_ex); |
241 | ip::tcp::socket socket8(ioc_ex, ip::tcp::v4()); |
242 | ip::tcp::socket socket9(ioc_ex, ip::tcp::v6()); |
243 | ip::tcp::socket socket10(ioc_ex, ip::tcp::endpoint(ip::tcp::v4(), 0)); |
244 | ip::tcp::socket socket11(ioc_ex, ip::tcp::endpoint(ip::tcp::v6(), 0)); |
245 | #if !defined(BOOST_ASIO_WINDOWS_RUNTIME) |
246 | ip::tcp::socket::native_handle_type native_socket2 |
247 | = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); |
248 | ip::tcp::socket socket12(ioc_ex, ip::tcp::v4(), native_socket2); |
249 | #endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME) |
250 | |
251 | ip::tcp::socket socket13(std::move(socket5)); |
252 | |
253 | // basic_stream_socket operators. |
254 | |
255 | socket1 = ip::tcp::socket(ioc); |
256 | socket1 = std::move(socket2); |
257 | |
258 | // basic_io_object functions. |
259 | |
260 | ip::tcp::socket::executor_type ex = socket1.get_executor(); |
261 | (void)ex; |
262 | |
263 | // basic_socket functions. |
264 | |
265 | ip::tcp::socket::lowest_layer_type& lowest_layer = socket1.lowest_layer(); |
266 | (void)lowest_layer; |
267 | |
268 | const ip::tcp::socket& socket14 = socket1; |
269 | const ip::tcp::socket::lowest_layer_type& lowest_layer2 |
270 | = socket14.lowest_layer(); |
271 | (void)lowest_layer2; |
272 | |
273 | socket1.open(protocol: ip::tcp::v4()); |
274 | socket1.open(protocol: ip::tcp::v6()); |
275 | socket1.open(protocol: ip::tcp::v4(), ec); |
276 | socket1.open(protocol: ip::tcp::v6(), ec); |
277 | |
278 | #if !defined(BOOST_ASIO_WINDOWS_RUNTIME) |
279 | ip::tcp::socket::native_handle_type native_socket3 |
280 | = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); |
281 | socket1.assign(protocol: ip::tcp::v4(), native_socket: native_socket3); |
282 | ip::tcp::socket::native_handle_type native_socket4 |
283 | = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); |
284 | socket1.assign(protocol: ip::tcp::v4(), native_socket: native_socket4, ec); |
285 | #endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME) |
286 | |
287 | bool is_open = socket1.is_open(); |
288 | (void)is_open; |
289 | |
290 | socket1.close(); |
291 | socket1.close(ec); |
292 | |
293 | socket1.release(); |
294 | socket1.release(ec); |
295 | |
296 | ip::tcp::socket::native_handle_type native_socket5 |
297 | = socket1.native_handle(); |
298 | (void)native_socket5; |
299 | |
300 | socket1.cancel(); |
301 | socket1.cancel(ec); |
302 | |
303 | bool at_mark1 = socket1.at_mark(); |
304 | (void)at_mark1; |
305 | bool at_mark2 = socket1.at_mark(ec); |
306 | (void)at_mark2; |
307 | |
308 | std::size_t available1 = socket1.available(); |
309 | (void)available1; |
310 | std::size_t available2 = socket1.available(ec); |
311 | (void)available2; |
312 | |
313 | socket1.bind(endpoint: ip::tcp::endpoint(ip::tcp::v4(), 0)); |
314 | socket1.bind(endpoint: ip::tcp::endpoint(ip::tcp::v6(), 0)); |
315 | socket1.bind(endpoint: ip::tcp::endpoint(ip::tcp::v4(), 0), ec); |
316 | socket1.bind(endpoint: ip::tcp::endpoint(ip::tcp::v6(), 0), ec); |
317 | |
318 | socket1.connect(peer_endpoint: ip::tcp::endpoint(ip::tcp::v4(), 0)); |
319 | socket1.connect(peer_endpoint: ip::tcp::endpoint(ip::tcp::v6(), 0)); |
320 | socket1.connect(peer_endpoint: ip::tcp::endpoint(ip::tcp::v4(), 0), ec); |
321 | socket1.connect(peer_endpoint: ip::tcp::endpoint(ip::tcp::v6(), 0), ec); |
322 | |
323 | socket1.async_connect(peer_endpoint: ip::tcp::endpoint(ip::tcp::v4(), 0), |
324 | token: connect_handler()); |
325 | socket1.async_connect(peer_endpoint: ip::tcp::endpoint(ip::tcp::v6(), 0), |
326 | token: connect_handler()); |
327 | socket1.async_connect(peer_endpoint: ip::tcp::endpoint(ip::tcp::v4(), 0), token&: immediate); |
328 | socket1.async_connect(peer_endpoint: ip::tcp::endpoint(ip::tcp::v6(), 0), token&: immediate); |
329 | int i1 = socket1.async_connect(peer_endpoint: ip::tcp::endpoint(ip::tcp::v4(), 0), token&: lazy); |
330 | (void)i1; |
331 | int i2 = socket1.async_connect(peer_endpoint: ip::tcp::endpoint(ip::tcp::v6(), 0), token&: lazy); |
332 | (void)i2; |
333 | |
334 | socket1.set_option(settable_socket_option1); |
335 | socket1.set_option(option: settable_socket_option1, ec); |
336 | socket1.set_option(settable_socket_option2); |
337 | socket1.set_option(option: settable_socket_option2, ec); |
338 | socket1.set_option(settable_socket_option3); |
339 | socket1.set_option(option: settable_socket_option3, ec); |
340 | |
341 | socket1.get_option(option&: gettable_socket_option1); |
342 | socket1.get_option(option&: gettable_socket_option1, ec); |
343 | socket1.get_option(option&: gettable_socket_option2); |
344 | socket1.get_option(option&: gettable_socket_option2, ec); |
345 | socket1.get_option(option&: gettable_socket_option3); |
346 | socket1.get_option(option&: gettable_socket_option3, ec); |
347 | |
348 | socket1.io_control(command&: io_control_command); |
349 | socket1.io_control(command&: io_control_command, ec); |
350 | |
351 | bool non_blocking1 = socket1.non_blocking(); |
352 | (void)non_blocking1; |
353 | socket1.non_blocking(mode: true); |
354 | socket1.non_blocking(mode: false, ec); |
355 | |
356 | bool non_blocking2 = socket1.native_non_blocking(); |
357 | (void)non_blocking2; |
358 | socket1.native_non_blocking(mode: true); |
359 | socket1.native_non_blocking(mode: false, ec); |
360 | |
361 | ip::tcp::endpoint endpoint1 = socket1.local_endpoint(); |
362 | (void)endpoint1; |
363 | ip::tcp::endpoint endpoint2 = socket1.local_endpoint(ec); |
364 | (void)endpoint2; |
365 | |
366 | ip::tcp::endpoint endpoint3 = socket1.remote_endpoint(); |
367 | (void)endpoint3; |
368 | ip::tcp::endpoint endpoint4 = socket1.remote_endpoint(ec); |
369 | (void)endpoint4; |
370 | |
371 | socket1.shutdown(what: socket_base::shutdown_both); |
372 | socket1.shutdown(what: socket_base::shutdown_both, ec); |
373 | |
374 | socket1.wait(w: socket_base::wait_read); |
375 | socket1.wait(w: socket_base::wait_write, ec); |
376 | |
377 | socket1.async_wait(w: socket_base::wait_read, token: wait_handler()); |
378 | socket1.async_wait(w: socket_base::wait_read, token&: immediate); |
379 | int i3 = socket1.async_wait(w: socket_base::wait_write, token&: lazy); |
380 | (void)i3; |
381 | |
382 | // basic_stream_socket functions. |
383 | |
384 | socket1.send(buffers: buffer(data&: mutable_char_buffer)); |
385 | socket1.send(buffers: buffer(data: const_char_buffer)); |
386 | socket1.send(buffers: mutable_buffers); |
387 | socket1.send(buffers: const_buffers); |
388 | socket1.send(buffers: null_buffers()); |
389 | socket1.send(buffers: buffer(data&: mutable_char_buffer), flags: in_flags); |
390 | socket1.send(buffers: buffer(data: const_char_buffer), flags: in_flags); |
391 | socket1.send(buffers: mutable_buffers, flags: in_flags); |
392 | socket1.send(buffers: const_buffers, flags: in_flags); |
393 | socket1.send(buffers: null_buffers(), flags: in_flags); |
394 | socket1.send(buffers: buffer(data&: mutable_char_buffer), flags: in_flags, ec); |
395 | socket1.send(buffers: buffer(data: const_char_buffer), flags: in_flags, ec); |
396 | socket1.send(buffers: mutable_buffers, flags: in_flags, ec); |
397 | socket1.send(buffers: const_buffers, flags: in_flags, ec); |
398 | socket1.send(buffers: null_buffers(), flags: in_flags, ec); |
399 | |
400 | socket1.async_send(buffers: buffer(data&: mutable_char_buffer), token: send_handler()); |
401 | socket1.async_send(buffers: buffer(data: const_char_buffer), token: send_handler()); |
402 | socket1.async_send(buffers: mutable_buffers, token: send_handler()); |
403 | socket1.async_send(buffers: const_buffers, token: send_handler()); |
404 | socket1.async_send(buffers: null_buffers(), token: send_handler()); |
405 | socket1.async_send(buffers: buffer(data&: mutable_char_buffer), flags: in_flags, token: send_handler()); |
406 | socket1.async_send(buffers: buffer(data: const_char_buffer), flags: in_flags, token: send_handler()); |
407 | socket1.async_send(buffers: mutable_buffers, flags: in_flags, token: send_handler()); |
408 | socket1.async_send(buffers: const_buffers, flags: in_flags, token: send_handler()); |
409 | socket1.async_send(buffers: null_buffers(), flags: in_flags, token: send_handler()); |
410 | socket1.async_send(buffers: buffer(data&: mutable_char_buffer), token&: immediate); |
411 | socket1.async_send(buffers: buffer(data: const_char_buffer), token&: immediate); |
412 | socket1.async_send(buffers: mutable_buffers, token&: immediate); |
413 | socket1.async_send(buffers: const_buffers, token&: immediate); |
414 | socket1.async_send(buffers: null_buffers(), token&: immediate); |
415 | socket1.async_send(buffers: buffer(data&: mutable_char_buffer), flags: in_flags, token&: immediate); |
416 | socket1.async_send(buffers: buffer(data: const_char_buffer), flags: in_flags, token&: immediate); |
417 | socket1.async_send(buffers: mutable_buffers, flags: in_flags, token&: immediate); |
418 | socket1.async_send(buffers: const_buffers, flags: in_flags, token&: immediate); |
419 | socket1.async_send(buffers: null_buffers(), flags: in_flags, token&: immediate); |
420 | int i4 = socket1.async_send(buffers: buffer(data&: mutable_char_buffer), token&: lazy); |
421 | (void)i4; |
422 | int i5 = socket1.async_send(buffers: buffer(data: const_char_buffer), token&: lazy); |
423 | (void)i5; |
424 | int i6 = socket1.async_send(buffers: mutable_buffers, token&: lazy); |
425 | (void)i6; |
426 | int i7 = socket1.async_send(buffers: const_buffers, token&: lazy); |
427 | (void)i7; |
428 | int i8 = socket1.async_send(buffers: null_buffers(), token&: lazy); |
429 | (void)i8; |
430 | int i9 = socket1.async_send(buffers: buffer(data&: mutable_char_buffer), flags: in_flags, token&: lazy); |
431 | (void)i9; |
432 | int i10 = socket1.async_send(buffers: buffer(data: const_char_buffer), flags: in_flags, token&: lazy); |
433 | (void)i10; |
434 | int i11 = socket1.async_send(buffers: mutable_buffers, flags: in_flags, token&: lazy); |
435 | (void)i11; |
436 | int i12 = socket1.async_send(buffers: const_buffers, flags: in_flags, token&: lazy); |
437 | (void)i12; |
438 | int i13 = socket1.async_send(buffers: null_buffers(), flags: in_flags, token&: lazy); |
439 | (void)i13; |
440 | |
441 | socket1.receive(buffers: buffer(data&: mutable_char_buffer)); |
442 | socket1.receive(buffers: mutable_buffers); |
443 | socket1.receive(buffers: null_buffers()); |
444 | socket1.receive(buffers: buffer(data&: mutable_char_buffer), flags: in_flags); |
445 | socket1.receive(buffers: mutable_buffers, flags: in_flags); |
446 | socket1.receive(buffers: null_buffers(), flags: in_flags); |
447 | socket1.receive(buffers: buffer(data&: mutable_char_buffer), flags: in_flags, ec); |
448 | socket1.receive(buffers: mutable_buffers, flags: in_flags, ec); |
449 | socket1.receive(buffers: null_buffers(), flags: in_flags, ec); |
450 | |
451 | socket1.async_receive(buffers: buffer(data&: mutable_char_buffer), token: receive_handler()); |
452 | socket1.async_receive(buffers: mutable_buffers, token: receive_handler()); |
453 | socket1.async_receive(buffers: null_buffers(), token: receive_handler()); |
454 | socket1.async_receive(buffers: buffer(data&: mutable_char_buffer), flags: in_flags, |
455 | token: receive_handler()); |
456 | socket1.async_receive(buffers: mutable_buffers, flags: in_flags, token: receive_handler()); |
457 | socket1.async_receive(buffers: null_buffers(), flags: in_flags, token: receive_handler()); |
458 | socket1.async_receive(buffers: buffer(data&: mutable_char_buffer), token&: immediate); |
459 | socket1.async_receive(buffers: mutable_buffers, token&: immediate); |
460 | socket1.async_receive(buffers: null_buffers(), token&: immediate); |
461 | socket1.async_receive(buffers: buffer(data&: mutable_char_buffer), flags: in_flags, token&: immediate); |
462 | socket1.async_receive(buffers: mutable_buffers, flags: in_flags, token&: immediate); |
463 | socket1.async_receive(buffers: null_buffers(), flags: in_flags, token&: immediate); |
464 | int i14 = socket1.async_receive(buffers: buffer(data&: mutable_char_buffer), token&: lazy); |
465 | (void)i14; |
466 | int i15 = socket1.async_receive(buffers: mutable_buffers, token&: lazy); |
467 | (void)i15; |
468 | int i16 = socket1.async_receive(buffers: null_buffers(), token&: lazy); |
469 | (void)i16; |
470 | int i17 = socket1.async_receive(buffers: buffer(data&: mutable_char_buffer), flags: in_flags, |
471 | token&: lazy); |
472 | (void)i17; |
473 | int i18 = socket1.async_receive(buffers: mutable_buffers, flags: in_flags, token&: lazy); |
474 | (void)i18; |
475 | int i19 = socket1.async_receive(buffers: null_buffers(), flags: in_flags, token&: lazy); |
476 | (void)i19; |
477 | |
478 | socket1.write_some(buffers: buffer(data&: mutable_char_buffer)); |
479 | socket1.write_some(buffers: buffer(data: const_char_buffer)); |
480 | socket1.write_some(buffers: mutable_buffers); |
481 | socket1.write_some(buffers: const_buffers); |
482 | socket1.write_some(buffers: null_buffers()); |
483 | socket1.write_some(buffers: buffer(data&: mutable_char_buffer), ec); |
484 | socket1.write_some(buffers: buffer(data: const_char_buffer), ec); |
485 | socket1.write_some(buffers: mutable_buffers, ec); |
486 | socket1.write_some(buffers: const_buffers, ec); |
487 | socket1.write_some(buffers: null_buffers(), ec); |
488 | |
489 | socket1.async_write_some(buffers: buffer(data&: mutable_char_buffer), token: write_some_handler()); |
490 | socket1.async_write_some(buffers: buffer(data: const_char_buffer), token: write_some_handler()); |
491 | socket1.async_write_some(buffers: mutable_buffers, token: write_some_handler()); |
492 | socket1.async_write_some(buffers: const_buffers, token: write_some_handler()); |
493 | socket1.async_write_some(buffers: null_buffers(), token: write_some_handler()); |
494 | socket1.async_write_some(buffers: buffer(data&: mutable_char_buffer), token&: immediate); |
495 | socket1.async_write_some(buffers: buffer(data: const_char_buffer), token&: immediate); |
496 | socket1.async_write_some(buffers: mutable_buffers, token&: immediate); |
497 | socket1.async_write_some(buffers: const_buffers, token&: immediate); |
498 | socket1.async_write_some(buffers: null_buffers(), token&: immediate); |
499 | int i20 = socket1.async_write_some(buffers: buffer(data&: mutable_char_buffer), token&: lazy); |
500 | (void)i20; |
501 | int i21 = socket1.async_write_some(buffers: buffer(data: const_char_buffer), token&: lazy); |
502 | (void)i21; |
503 | int i22 = socket1.async_write_some(buffers: mutable_buffers, token&: lazy); |
504 | (void)i22; |
505 | int i23 = socket1.async_write_some(buffers: const_buffers, token&: lazy); |
506 | (void)i23; |
507 | int i24 = socket1.async_write_some(buffers: null_buffers(), token&: lazy); |
508 | (void)i24; |
509 | |
510 | socket1.read_some(buffers: buffer(data&: mutable_char_buffer)); |
511 | socket1.read_some(buffers: mutable_buffers); |
512 | socket1.read_some(buffers: null_buffers()); |
513 | socket1.read_some(buffers: buffer(data&: mutable_char_buffer), ec); |
514 | socket1.read_some(buffers: mutable_buffers, ec); |
515 | socket1.read_some(buffers: null_buffers(), ec); |
516 | |
517 | socket1.async_read_some(buffers: buffer(data&: mutable_char_buffer), token: read_some_handler()); |
518 | socket1.async_read_some(buffers: mutable_buffers, token: read_some_handler()); |
519 | socket1.async_read_some(buffers: null_buffers(), token: read_some_handler()); |
520 | socket1.async_read_some(buffers: buffer(data&: mutable_char_buffer), token&: immediate); |
521 | socket1.async_read_some(buffers: mutable_buffers, token&: immediate); |
522 | socket1.async_read_some(buffers: null_buffers(), token&: immediate); |
523 | int i25 = socket1.async_read_some(buffers: buffer(data&: mutable_char_buffer), token&: lazy); |
524 | (void)i25; |
525 | int i26 = socket1.async_read_some(buffers: mutable_buffers, token&: lazy); |
526 | (void)i26; |
527 | int i27 = socket1.async_read_some(buffers: null_buffers(), token&: lazy); |
528 | (void)i27; |
529 | } |
530 | catch (std::exception&) |
531 | { |
532 | } |
533 | } |
534 | |
535 | } // namespace ip_tcp_socket_compile |
536 | |
537 | //------------------------------------------------------------------------------ |
538 | |
539 | // ip_tcp_socket_runtime test |
540 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~ |
541 | // The following test checks the runtime operation of the ip::tcp::socket class. |
542 | |
543 | namespace ip_tcp_socket_runtime { |
544 | |
545 | static const char write_data[] |
546 | = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" ; |
547 | |
548 | void handle_read_noop(const boost::system::error_code& err, |
549 | size_t bytes_transferred, bool* called) |
550 | { |
551 | *called = true; |
552 | BOOST_ASIO_CHECK(!err); |
553 | BOOST_ASIO_CHECK(bytes_transferred == 0); |
554 | } |
555 | |
556 | void handle_write_noop(const boost::system::error_code& err, |
557 | size_t bytes_transferred, bool* called) |
558 | { |
559 | *called = true; |
560 | BOOST_ASIO_CHECK(!err); |
561 | BOOST_ASIO_CHECK(bytes_transferred == 0); |
562 | } |
563 | |
564 | void handle_read(const boost::system::error_code& err, |
565 | size_t bytes_transferred, bool* called) |
566 | { |
567 | *called = true; |
568 | BOOST_ASIO_CHECK(!err); |
569 | BOOST_ASIO_CHECK(bytes_transferred == sizeof(write_data)); |
570 | } |
571 | |
572 | void handle_write(const boost::system::error_code& err, |
573 | size_t bytes_transferred, bool* called) |
574 | { |
575 | *called = true; |
576 | BOOST_ASIO_CHECK(!err); |
577 | BOOST_ASIO_CHECK(bytes_transferred == sizeof(write_data)); |
578 | } |
579 | |
580 | void handle_read_cancel(const boost::system::error_code& err, |
581 | size_t bytes_transferred, bool* called) |
582 | { |
583 | *called = true; |
584 | BOOST_ASIO_CHECK(err == boost::asio::error::operation_aborted); |
585 | BOOST_ASIO_CHECK(bytes_transferred == 0); |
586 | } |
587 | |
588 | void handle_read_eof(const boost::system::error_code& err, |
589 | size_t bytes_transferred, bool* called) |
590 | { |
591 | *called = true; |
592 | BOOST_ASIO_CHECK(err == boost::asio::error::eof); |
593 | BOOST_ASIO_CHECK(bytes_transferred == 0); |
594 | } |
595 | |
596 | void test() |
597 | { |
598 | using namespace std; // For memcmp. |
599 | using namespace boost::asio; |
600 | namespace ip = boost::asio::ip; |
601 | |
602 | namespace bindns = std; |
603 | using bindns::placeholders::_1; |
604 | using bindns::placeholders::_2; |
605 | |
606 | io_context ioc; |
607 | |
608 | ip::tcp::acceptor acceptor(ioc, ip::tcp::endpoint(ip::tcp::v4(), 0)); |
609 | ip::tcp::endpoint server_endpoint = acceptor.local_endpoint(); |
610 | server_endpoint.address(addr: ip::address_v4::loopback()); |
611 | |
612 | ip::tcp::socket client_side_socket(ioc); |
613 | ip::tcp::socket server_side_socket(ioc); |
614 | |
615 | client_side_socket.connect(peer_endpoint: server_endpoint); |
616 | acceptor.accept(peer&: server_side_socket); |
617 | |
618 | // No-op read. |
619 | |
620 | bool read_noop_completed = false; |
621 | client_side_socket.async_read_some( |
622 | buffers: boost::asio::mutable_buffer(0, 0), |
623 | token: bindns::bind(f&: handle_read_noop, |
624 | args: _1, args: _2, args: &read_noop_completed)); |
625 | |
626 | ioc.run(); |
627 | BOOST_ASIO_CHECK(read_noop_completed); |
628 | |
629 | // No-op write. |
630 | |
631 | bool write_noop_completed = false; |
632 | client_side_socket.async_write_some( |
633 | buffers: boost::asio::const_buffer(0, 0), |
634 | token: bindns::bind(f&: handle_write_noop, |
635 | args: _1, args: _2, args: &write_noop_completed)); |
636 | |
637 | ioc.restart(); |
638 | ioc.run(); |
639 | BOOST_ASIO_CHECK(write_noop_completed); |
640 | |
641 | // Read and write to transfer data. |
642 | |
643 | char read_buffer[sizeof(write_data)]; |
644 | bool read_completed = false; |
645 | boost::asio::async_read(s&: client_side_socket, |
646 | buffers: boost::asio::buffer(data&: read_buffer), |
647 | token: bindns::bind(f&: handle_read, |
648 | args: _1, args: _2, args: &read_completed)); |
649 | |
650 | bool write_completed = false; |
651 | boost::asio::async_write(s&: server_side_socket, |
652 | buffers: boost::asio::buffer(data: write_data), |
653 | token: bindns::bind(f&: handle_write, |
654 | args: _1, args: _2, args: &write_completed)); |
655 | |
656 | ioc.restart(); |
657 | ioc.run(); |
658 | BOOST_ASIO_CHECK(read_completed); |
659 | BOOST_ASIO_CHECK(write_completed); |
660 | BOOST_ASIO_CHECK(memcmp(read_buffer, write_data, sizeof(write_data)) == 0); |
661 | |
662 | // Cancelled read. |
663 | |
664 | bool read_cancel_completed = false; |
665 | boost::asio::async_read(s&: server_side_socket, |
666 | buffers: boost::asio::buffer(data&: read_buffer), |
667 | token: bindns::bind(f&: handle_read_cancel, |
668 | args: _1, args: _2, args: &read_cancel_completed)); |
669 | |
670 | ioc.restart(); |
671 | ioc.poll(); |
672 | BOOST_ASIO_CHECK(!read_cancel_completed); |
673 | |
674 | server_side_socket.cancel(); |
675 | |
676 | ioc.restart(); |
677 | ioc.run(); |
678 | BOOST_ASIO_CHECK(read_cancel_completed); |
679 | |
680 | // A read when the peer closes socket should fail with eof. |
681 | |
682 | bool read_eof_completed = false; |
683 | boost::asio::async_read(s&: client_side_socket, |
684 | buffers: boost::asio::buffer(data&: read_buffer), |
685 | token: bindns::bind(f&: handle_read_eof, |
686 | args: _1, args: _2, args: &read_eof_completed)); |
687 | |
688 | server_side_socket.close(); |
689 | |
690 | ioc.restart(); |
691 | ioc.run(); |
692 | BOOST_ASIO_CHECK(read_eof_completed); |
693 | } |
694 | |
695 | } // namespace ip_tcp_socket_runtime |
696 | |
697 | //------------------------------------------------------------------------------ |
698 | |
699 | // ip_tcp_acceptor_compile test |
700 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
701 | // The following test checks that all public member functions on the class |
702 | // ip::tcp::acceptor compile and link correctly. Runtime failures are ignored. |
703 | |
704 | namespace ip_tcp_acceptor_compile { |
705 | |
706 | struct wait_handler |
707 | { |
708 | wait_handler() {} |
709 | void operator()(const boost::system::error_code&) {} |
710 | wait_handler(wait_handler&&) {} |
711 | private: |
712 | wait_handler(const wait_handler&); |
713 | }; |
714 | |
715 | struct accept_handler |
716 | { |
717 | accept_handler() {} |
718 | void operator()(const boost::system::error_code&) {} |
719 | accept_handler(accept_handler&&) {} |
720 | private: |
721 | accept_handler(const accept_handler&); |
722 | }; |
723 | |
724 | struct move_accept_handler |
725 | { |
726 | move_accept_handler() {} |
727 | void operator()( |
728 | const boost::system::error_code&, boost::asio::ip::tcp::socket) {} |
729 | move_accept_handler(move_accept_handler&&) {} |
730 | private: |
731 | move_accept_handler(const move_accept_handler&) {} |
732 | }; |
733 | |
734 | struct move_accept_ioc_handler |
735 | { |
736 | move_accept_ioc_handler() {} |
737 | void operator()(const boost::system::error_code&, |
738 | boost::asio::basic_stream_socket<boost::asio::ip::tcp, |
739 | boost::asio::io_context::executor_type>) {} |
740 | move_accept_ioc_handler(move_accept_handler&&) {} |
741 | private: |
742 | move_accept_ioc_handler(const move_accept_handler&) {} |
743 | }; |
744 | |
745 | void test() |
746 | { |
747 | using namespace boost::asio; |
748 | namespace ip = boost::asio::ip; |
749 | |
750 | try |
751 | { |
752 | io_context ioc; |
753 | const io_context::executor_type ioc_ex = ioc.get_executor(); |
754 | ip::tcp::socket peer_socket1(ioc); |
755 | boost::asio::basic_stream_socket<ip::tcp, |
756 | io_context::executor_type> peer_socket2(ioc); |
757 | ip::tcp::endpoint peer_endpoint; |
758 | archetypes::settable_socket_option<void> settable_socket_option1; |
759 | archetypes::settable_socket_option<int> settable_socket_option2; |
760 | archetypes::settable_socket_option<double> settable_socket_option3; |
761 | archetypes::gettable_socket_option<void> gettable_socket_option1; |
762 | archetypes::gettable_socket_option<int> gettable_socket_option2; |
763 | archetypes::gettable_socket_option<double> gettable_socket_option3; |
764 | archetypes::io_control_command io_control_command; |
765 | archetypes::immediate_handler immediate; |
766 | archetypes::lazy_handler lazy; |
767 | boost::system::error_code ec; |
768 | |
769 | // basic_socket_acceptor constructors. |
770 | |
771 | ip::tcp::acceptor acceptor1(ioc); |
772 | ip::tcp::acceptor acceptor2(ioc, ip::tcp::v4()); |
773 | ip::tcp::acceptor acceptor3(ioc, ip::tcp::v6()); |
774 | ip::tcp::acceptor acceptor4(ioc, ip::tcp::endpoint(ip::tcp::v4(), 0)); |
775 | ip::tcp::acceptor acceptor5(ioc, ip::tcp::endpoint(ip::tcp::v6(), 0)); |
776 | #if !defined(BOOST_ASIO_WINDOWS_RUNTIME) |
777 | ip::tcp::acceptor::native_handle_type native_acceptor1 |
778 | = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); |
779 | ip::tcp::acceptor acceptor6(ioc, ip::tcp::v4(), native_acceptor1); |
780 | #endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME) |
781 | |
782 | ip::tcp::acceptor acceptor7(ioc_ex); |
783 | ip::tcp::acceptor acceptor8(ioc_ex, ip::tcp::v4()); |
784 | ip::tcp::acceptor acceptor9(ioc_ex, ip::tcp::v6()); |
785 | ip::tcp::acceptor acceptor10(ioc_ex, ip::tcp::endpoint(ip::tcp::v4(), 0)); |
786 | ip::tcp::acceptor acceptor11(ioc_ex, ip::tcp::endpoint(ip::tcp::v6(), 0)); |
787 | #if !defined(BOOST_ASIO_WINDOWS_RUNTIME) |
788 | ip::tcp::acceptor::native_handle_type native_acceptor2 |
789 | = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); |
790 | ip::tcp::acceptor acceptor12(ioc_ex, ip::tcp::v4(), native_acceptor2); |
791 | #endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME) |
792 | |
793 | ip::tcp::acceptor acceptor13(std::move(acceptor5)); |
794 | |
795 | // basic_socket_acceptor operators. |
796 | |
797 | acceptor1 = ip::tcp::acceptor(ioc); |
798 | acceptor1 = std::move(acceptor2); |
799 | |
800 | // basic_io_object functions. |
801 | |
802 | ip::tcp::acceptor::executor_type ex = acceptor1.get_executor(); |
803 | (void)ex; |
804 | |
805 | // basic_socket_acceptor functions. |
806 | |
807 | acceptor1.open(protocol: ip::tcp::v4()); |
808 | acceptor1.open(protocol: ip::tcp::v6()); |
809 | acceptor1.open(protocol: ip::tcp::v4(), ec); |
810 | acceptor1.open(protocol: ip::tcp::v6(), ec); |
811 | |
812 | #if !defined(BOOST_ASIO_WINDOWS_RUNTIME) |
813 | ip::tcp::acceptor::native_handle_type native_acceptor3 |
814 | = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); |
815 | acceptor1.assign(protocol: ip::tcp::v4(), native_acceptor: native_acceptor3); |
816 | ip::tcp::acceptor::native_handle_type native_acceptor4 |
817 | = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); |
818 | acceptor1.assign(protocol: ip::tcp::v4(), native_acceptor: native_acceptor4, ec); |
819 | #endif // !defined(BOOST_ASIO_WINDOWS_RUNTIME) |
820 | |
821 | bool is_open = acceptor1.is_open(); |
822 | (void)is_open; |
823 | |
824 | acceptor1.close(); |
825 | acceptor1.close(ec); |
826 | |
827 | acceptor1.release(); |
828 | acceptor1.release(ec); |
829 | |
830 | ip::tcp::acceptor::native_handle_type native_acceptor5 |
831 | = acceptor1.native_handle(); |
832 | (void)native_acceptor5; |
833 | |
834 | acceptor1.cancel(); |
835 | acceptor1.cancel(ec); |
836 | |
837 | acceptor1.bind(endpoint: ip::tcp::endpoint(ip::tcp::v4(), 0)); |
838 | acceptor1.bind(endpoint: ip::tcp::endpoint(ip::tcp::v6(), 0)); |
839 | acceptor1.bind(endpoint: ip::tcp::endpoint(ip::tcp::v4(), 0), ec); |
840 | acceptor1.bind(endpoint: ip::tcp::endpoint(ip::tcp::v6(), 0), ec); |
841 | |
842 | acceptor1.set_option(settable_socket_option1); |
843 | acceptor1.set_option(option: settable_socket_option1, ec); |
844 | acceptor1.set_option(settable_socket_option2); |
845 | acceptor1.set_option(option: settable_socket_option2, ec); |
846 | acceptor1.set_option(settable_socket_option3); |
847 | acceptor1.set_option(option: settable_socket_option3, ec); |
848 | |
849 | acceptor1.get_option(option&: gettable_socket_option1); |
850 | acceptor1.get_option(option&: gettable_socket_option1, ec); |
851 | acceptor1.get_option(option&: gettable_socket_option2); |
852 | acceptor1.get_option(option&: gettable_socket_option2, ec); |
853 | acceptor1.get_option(option&: gettable_socket_option3); |
854 | acceptor1.get_option(option&: gettable_socket_option3, ec); |
855 | |
856 | acceptor1.io_control(command&: io_control_command); |
857 | acceptor1.io_control(command&: io_control_command, ec); |
858 | |
859 | bool non_blocking1 = acceptor1.non_blocking(); |
860 | (void)non_blocking1; |
861 | acceptor1.non_blocking(mode: true); |
862 | acceptor1.non_blocking(mode: false, ec); |
863 | |
864 | bool non_blocking2 = acceptor1.native_non_blocking(); |
865 | (void)non_blocking2; |
866 | acceptor1.native_non_blocking(mode: true); |
867 | acceptor1.native_non_blocking(mode: false, ec); |
868 | |
869 | ip::tcp::endpoint endpoint1 = acceptor1.local_endpoint(); |
870 | (void)endpoint1; |
871 | ip::tcp::endpoint endpoint2 = acceptor1.local_endpoint(ec); |
872 | (void)endpoint2; |
873 | |
874 | acceptor1.wait(w: socket_base::wait_read); |
875 | acceptor1.wait(w: socket_base::wait_write, ec); |
876 | |
877 | acceptor1.async_wait(w: socket_base::wait_read, token: wait_handler()); |
878 | acceptor1.async_wait(w: socket_base::wait_read, token&: immediate); |
879 | int i1 = acceptor1.async_wait(w: socket_base::wait_write, token&: lazy); |
880 | (void)i1; |
881 | |
882 | acceptor1.accept(peer&: peer_socket1); |
883 | acceptor1.accept(peer&: peer_socket1, ec); |
884 | acceptor1.accept(peer&: peer_socket1, peer_endpoint); |
885 | acceptor1.accept(peer&: peer_socket1, peer_endpoint, ec); |
886 | |
887 | acceptor1.accept(peer&: peer_socket2); |
888 | acceptor1.accept(peer&: peer_socket2, ec); |
889 | acceptor1.accept(peer&: peer_socket2, peer_endpoint); |
890 | acceptor1.accept(peer&: peer_socket2, peer_endpoint, ec); |
891 | |
892 | peer_socket1 = acceptor1.accept(); |
893 | peer_socket1 = acceptor1.accept(context&: ioc); |
894 | peer_socket1 = acceptor1.accept(ex: ioc_ex); |
895 | peer_socket1 = acceptor1.accept(peer_endpoint); |
896 | peer_socket1 = acceptor1.accept(context&: ioc, peer_endpoint); |
897 | peer_socket1 = acceptor1.accept(ex: ioc_ex, peer_endpoint); |
898 | (void)peer_socket1; |
899 | |
900 | peer_socket2 = acceptor1.accept(context&: ioc); |
901 | peer_socket2 = acceptor1.accept(ex: ioc_ex); |
902 | peer_socket2 = acceptor1.accept(context&: ioc, peer_endpoint); |
903 | peer_socket2 = acceptor1.accept(ex: ioc_ex, peer_endpoint); |
904 | (void)peer_socket2; |
905 | |
906 | acceptor1.async_accept(peer&: peer_socket1, token: accept_handler()); |
907 | acceptor1.async_accept(peer&: peer_socket1, peer_endpoint, token: accept_handler()); |
908 | acceptor1.async_accept(peer&: peer_socket1, token&: immediate); |
909 | acceptor1.async_accept(peer&: peer_socket1, peer_endpoint, token&: immediate); |
910 | int i2 = acceptor1.async_accept(peer&: peer_socket1, token&: lazy); |
911 | (void)i2; |
912 | int i3 = acceptor1.async_accept(peer&: peer_socket1, peer_endpoint, token&: lazy); |
913 | (void)i3; |
914 | |
915 | acceptor1.async_accept(peer&: peer_socket2, token: accept_handler()); |
916 | acceptor1.async_accept(peer&: peer_socket2, peer_endpoint, token: accept_handler()); |
917 | acceptor1.async_accept(peer&: peer_socket2, token&: immediate); |
918 | acceptor1.async_accept(peer&: peer_socket2, peer_endpoint, token&: immediate); |
919 | int i4 = acceptor1.async_accept(peer&: peer_socket2, token&: lazy); |
920 | (void)i4; |
921 | int i5 = acceptor1.async_accept(peer&: peer_socket2, peer_endpoint, token&: lazy); |
922 | (void)i5; |
923 | |
924 | acceptor1.async_accept(token: move_accept_handler()); |
925 | acceptor1.async_accept(context&: ioc, token: move_accept_handler()); |
926 | acceptor1.async_accept(ex: ioc_ex, token: move_accept_handler()); |
927 | acceptor1.async_accept(ex: ioc_ex, token: move_accept_ioc_handler()); |
928 | acceptor1.async_accept(peer_endpoint, token: move_accept_handler()); |
929 | acceptor1.async_accept(context&: ioc, peer_endpoint, token: move_accept_handler()); |
930 | acceptor1.async_accept(ex: ioc_ex, peer_endpoint, token: move_accept_handler()); |
931 | acceptor1.async_accept(ex: ioc_ex, peer_endpoint, token: move_accept_ioc_handler()); |
932 | acceptor1.async_accept(token&: immediate); |
933 | acceptor1.async_accept(context&: ioc, token&: immediate); |
934 | acceptor1.async_accept(ex: ioc_ex, token&: immediate); |
935 | acceptor1.async_accept(peer_endpoint, token&: immediate); |
936 | acceptor1.async_accept(context&: ioc, peer_endpoint, token&: immediate); |
937 | acceptor1.async_accept(ex: ioc_ex, peer_endpoint, token&: immediate); |
938 | } |
939 | catch (std::exception&) |
940 | { |
941 | } |
942 | } |
943 | |
944 | } // namespace ip_tcp_acceptor_compile |
945 | |
946 | //------------------------------------------------------------------------------ |
947 | |
948 | // ip_tcp_acceptor_runtime test |
949 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
950 | // The following test checks the runtime operation of the ip::tcp::acceptor |
951 | // class. |
952 | |
953 | namespace ip_tcp_acceptor_runtime { |
954 | |
955 | void handle_accept(const boost::system::error_code& err) |
956 | { |
957 | BOOST_ASIO_CHECK(!err); |
958 | } |
959 | |
960 | void handle_connect(const boost::system::error_code& err) |
961 | { |
962 | BOOST_ASIO_CHECK(!err); |
963 | } |
964 | |
965 | void test() |
966 | { |
967 | using namespace boost::asio; |
968 | namespace ip = boost::asio::ip; |
969 | |
970 | io_context ioc; |
971 | |
972 | ip::tcp::acceptor acceptor(ioc, ip::tcp::endpoint(ip::tcp::v4(), 0)); |
973 | ip::tcp::endpoint server_endpoint = acceptor.local_endpoint(); |
974 | server_endpoint.address(addr: ip::address_v4::loopback()); |
975 | |
976 | ip::tcp::socket client_side_socket(ioc); |
977 | ip::tcp::socket server_side_socket(ioc); |
978 | |
979 | client_side_socket.connect(peer_endpoint: server_endpoint); |
980 | acceptor.accept(peer&: server_side_socket); |
981 | |
982 | client_side_socket.close(); |
983 | server_side_socket.close(); |
984 | |
985 | client_side_socket.connect(peer_endpoint: server_endpoint); |
986 | ip::tcp::endpoint client_endpoint; |
987 | acceptor.accept(peer&: server_side_socket, peer_endpoint&: client_endpoint); |
988 | |
989 | ip::tcp::endpoint client_side_local_endpoint |
990 | = client_side_socket.local_endpoint(); |
991 | BOOST_ASIO_CHECK(client_side_local_endpoint.port() == client_endpoint.port()); |
992 | |
993 | ip::tcp::endpoint server_side_remote_endpoint |
994 | = server_side_socket.remote_endpoint(); |
995 | BOOST_ASIO_CHECK(server_side_remote_endpoint.port() |
996 | == client_endpoint.port()); |
997 | |
998 | client_side_socket.close(); |
999 | server_side_socket.close(); |
1000 | |
1001 | acceptor.async_accept(peer&: server_side_socket, token: &handle_accept); |
1002 | client_side_socket.async_connect(peer_endpoint: server_endpoint, token: &handle_connect); |
1003 | |
1004 | ioc.run(); |
1005 | |
1006 | client_side_socket.close(); |
1007 | server_side_socket.close(); |
1008 | |
1009 | acceptor.async_accept(peer&: server_side_socket, peer_endpoint&: client_endpoint, token: &handle_accept); |
1010 | client_side_socket.async_connect(peer_endpoint: server_endpoint, token: &handle_connect); |
1011 | |
1012 | ioc.restart(); |
1013 | ioc.run(); |
1014 | |
1015 | client_side_local_endpoint = client_side_socket.local_endpoint(); |
1016 | BOOST_ASIO_CHECK(client_side_local_endpoint.port() == client_endpoint.port()); |
1017 | |
1018 | server_side_remote_endpoint = server_side_socket.remote_endpoint(); |
1019 | BOOST_ASIO_CHECK(server_side_remote_endpoint.port() |
1020 | == client_endpoint.port()); |
1021 | } |
1022 | |
1023 | } // namespace ip_tcp_acceptor_runtime |
1024 | |
1025 | //------------------------------------------------------------------------------ |
1026 | |
1027 | // ip_tcp_resolver_compile test |
1028 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
1029 | // The following test checks that all public member functions on the class |
1030 | // ip::tcp::resolver compile and link correctly. Runtime failures are ignored. |
1031 | |
1032 | namespace ip_tcp_resolver_compile { |
1033 | |
1034 | struct resolve_handler |
1035 | { |
1036 | resolve_handler() {} |
1037 | void operator()(const boost::system::error_code&, |
1038 | boost::asio::ip::tcp::resolver::results_type) {} |
1039 | resolve_handler(resolve_handler&&) {} |
1040 | private: |
1041 | resolve_handler(const resolve_handler&); |
1042 | }; |
1043 | |
1044 | #if !defined(BOOST_ASIO_NO_DEPRECATED) |
1045 | struct legacy_resolve_handler |
1046 | { |
1047 | legacy_resolve_handler() {} |
1048 | void operator()(const boost::system::error_code&, |
1049 | boost::asio::ip::tcp::resolver::iterator) {} |
1050 | legacy_resolve_handler(legacy_resolve_handler&&) {} |
1051 | private: |
1052 | legacy_resolve_handler(const legacy_resolve_handler&); |
1053 | }; |
1054 | #endif // !defined(BOOST_ASIO_NO_DEPRECATED) |
1055 | |
1056 | void test() |
1057 | { |
1058 | using namespace boost::asio; |
1059 | namespace ip = boost::asio::ip; |
1060 | |
1061 | try |
1062 | { |
1063 | io_context ioc; |
1064 | const io_context::executor_type ioc_ex = ioc.get_executor(); |
1065 | archetypes::lazy_handler lazy; |
1066 | boost::system::error_code ec; |
1067 | #if !defined(BOOST_ASIO_NO_DEPRECATED) |
1068 | ip::tcp::resolver::query q(ip::tcp::v4(), "localhost" , "0" ); |
1069 | #endif // !defined(BOOST_ASIO_NO_DEPRECATED) |
1070 | ip::tcp::endpoint e(ip::address_v4::loopback(), 0); |
1071 | |
1072 | // basic_resolver constructors. |
1073 | |
1074 | ip::tcp::resolver resolver(ioc); |
1075 | ip::tcp::resolver resolver2(ioc_ex); |
1076 | |
1077 | ip::tcp::resolver resolver3(std::move(resolver)); |
1078 | |
1079 | // basic_resolver operators. |
1080 | |
1081 | resolver = ip::tcp::resolver(ioc); |
1082 | resolver = std::move(resolver3); |
1083 | |
1084 | // basic_io_object functions. |
1085 | |
1086 | ip::tcp::resolver::executor_type ex = resolver.get_executor(); |
1087 | (void)ex; |
1088 | |
1089 | // basic_resolver functions. |
1090 | |
1091 | resolver.cancel(); |
1092 | |
1093 | #if !defined(BOOST_ASIO_NO_DEPRECATED) |
1094 | ip::tcp::resolver::results_type results1 = resolver.resolve(q); |
1095 | (void)results1; |
1096 | |
1097 | ip::tcp::resolver::results_type results2 = resolver.resolve(q, ec); |
1098 | (void)results2; |
1099 | #endif // !defined(BOOST_ASIO_NO_DEPRECATED) |
1100 | |
1101 | ip::tcp::resolver::results_type results3 = resolver.resolve(host: "" , service: "" ); |
1102 | (void)results3; |
1103 | |
1104 | ip::tcp::resolver::results_type results4 = resolver.resolve(host: "" , service: "" , ec); |
1105 | (void)results4; |
1106 | |
1107 | ip::tcp::resolver::results_type results5 = |
1108 | resolver.resolve(host: "" , service: "" , resolve_flags: ip::tcp::resolver::flags()); |
1109 | (void)results5; |
1110 | |
1111 | ip::tcp::resolver::results_type results6 = |
1112 | resolver.resolve(host: "" , service: "" , resolve_flags: ip::tcp::resolver::flags(), ec); |
1113 | (void)results6; |
1114 | |
1115 | ip::tcp::resolver::results_type results7 = |
1116 | resolver.resolve(protocol: ip::tcp::v4(), host: "" , service: "" ); |
1117 | (void)results7; |
1118 | |
1119 | ip::tcp::resolver::results_type results8 = |
1120 | resolver.resolve(protocol: ip::tcp::v4(), host: "" , service: "" , ec); |
1121 | (void)results8; |
1122 | |
1123 | ip::tcp::resolver::results_type results9 = |
1124 | resolver.resolve(protocol: ip::tcp::v4(), host: "" , service: "" , resolve_flags: ip::tcp::resolver::flags()); |
1125 | (void)results9; |
1126 | |
1127 | ip::tcp::resolver::results_type results10 = |
1128 | resolver.resolve(protocol: ip::tcp::v4(), host: "" , service: "" , resolve_flags: ip::tcp::resolver::flags(), ec); |
1129 | (void)results10; |
1130 | |
1131 | ip::tcp::resolver::results_type results11 = resolver.resolve(e); |
1132 | (void)results11; |
1133 | |
1134 | ip::tcp::resolver::results_type results12 = resolver.resolve(e, ec); |
1135 | (void)results12; |
1136 | |
1137 | #if !defined(BOOST_ASIO_NO_DEPRECATED) |
1138 | resolver.async_resolve(q, token: resolve_handler()); |
1139 | resolver.async_resolve(q, token: legacy_resolve_handler()); |
1140 | int i1 = resolver.async_resolve(q, token&: lazy); |
1141 | (void)i1; |
1142 | #endif // !defined(BOOST_ASIO_NO_DEPRECATED) |
1143 | |
1144 | resolver.async_resolve(host: "" , service: "" , token: resolve_handler()); |
1145 | #if !defined(BOOST_ASIO_NO_DEPRECATED) |
1146 | resolver.async_resolve(host: "" , service: "" , token: legacy_resolve_handler()); |
1147 | #endif // !defined(BOOST_ASIO_NO_DEPRECATED) |
1148 | int i2 = resolver.async_resolve(host: "" , service: "" , token&: lazy); |
1149 | (void)i2; |
1150 | |
1151 | resolver.async_resolve(host: "" , service: "" , |
1152 | resolve_flags: ip::tcp::resolver::flags(), token: resolve_handler()); |
1153 | #if !defined(BOOST_ASIO_NO_DEPRECATED) |
1154 | resolver.async_resolve(host: "" , service: "" , |
1155 | resolve_flags: ip::tcp::resolver::flags(), token: legacy_resolve_handler()); |
1156 | #endif // !defined(BOOST_ASIO_NO_DEPRECATED) |
1157 | int i3 = resolver.async_resolve(host: "" , service: "" , |
1158 | resolve_flags: ip::tcp::resolver::flags(), token&: lazy); |
1159 | (void)i3; |
1160 | |
1161 | resolver.async_resolve(protocol: ip::tcp::v4(), host: "" , service: "" , token: resolve_handler()); |
1162 | #if !defined(BOOST_ASIO_NO_DEPRECATED) |
1163 | resolver.async_resolve(protocol: ip::tcp::v4(), host: "" , service: "" , token: legacy_resolve_handler()); |
1164 | #endif // !defined(BOOST_ASIO_NO_DEPRECATED) |
1165 | int i4 = resolver.async_resolve(protocol: ip::tcp::v4(), host: "" , service: "" , token&: lazy); |
1166 | (void)i4; |
1167 | |
1168 | resolver.async_resolve(protocol: ip::tcp::v4(), |
1169 | host: "" , service: "" , resolve_flags: ip::tcp::resolver::flags(), token: resolve_handler()); |
1170 | #if !defined(BOOST_ASIO_NO_DEPRECATED) |
1171 | resolver.async_resolve(protocol: ip::tcp::v4(), |
1172 | host: "" , service: "" , resolve_flags: ip::tcp::resolver::flags(), token: legacy_resolve_handler()); |
1173 | #endif // !defined(BOOST_ASIO_NO_DEPRECATED) |
1174 | int i5 = resolver.async_resolve(protocol: ip::tcp::v4(), |
1175 | host: "" , service: "" , resolve_flags: ip::tcp::resolver::flags(), token&: lazy); |
1176 | (void)i5; |
1177 | |
1178 | resolver.async_resolve(e, token: resolve_handler()); |
1179 | #if !defined(BOOST_ASIO_NO_DEPRECATED) |
1180 | resolver.async_resolve(e, token: legacy_resolve_handler()); |
1181 | #endif // !defined(BOOST_ASIO_NO_DEPRECATED) |
1182 | int i6 = resolver.async_resolve(e, token&: lazy); |
1183 | (void)i6; |
1184 | } |
1185 | catch (std::exception&) |
1186 | { |
1187 | } |
1188 | } |
1189 | |
1190 | } // namespace ip_tcp_resolver_compile |
1191 | |
1192 | //------------------------------------------------------------------------------ |
1193 | |
1194 | // ip_tcp_resolver_entry_compile test |
1195 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
1196 | // The following test checks that all public member functions on the class |
1197 | // ip::tcp::resolver::entry compile and link correctly. Runtime failures are |
1198 | // ignored. |
1199 | |
1200 | namespace ip_tcp_resolver_entry_compile { |
1201 | |
1202 | void test() |
1203 | { |
1204 | using namespace boost::asio; |
1205 | namespace ip = boost::asio::ip; |
1206 | const ip::tcp::endpoint endpoint; |
1207 | const std::string host_name; |
1208 | const std::string service_name; |
1209 | const std::allocator<char> alloc; |
1210 | |
1211 | try |
1212 | { |
1213 | // basic_resolver_entry constructors. |
1214 | |
1215 | const ip::basic_resolver_entry<ip::tcp> entry1; |
1216 | ip::basic_resolver_entry<ip::tcp> entry2(endpoint, host_name, service_name); |
1217 | ip::basic_resolver_entry<ip::tcp> entry3(entry1); |
1218 | ip::basic_resolver_entry<ip::tcp> entry4(std::move(entry2)); |
1219 | |
1220 | // basic_resolver_entry functions. |
1221 | |
1222 | ip::tcp::endpoint e1 = entry1.endpoint(); |
1223 | (void)e1; |
1224 | |
1225 | ip::tcp::endpoint e2 = entry1; |
1226 | (void)e2; |
1227 | |
1228 | std::string s1 = entry1.host_name(); |
1229 | (void)s1; |
1230 | |
1231 | std::string s2 = entry1.host_name(alloc); |
1232 | (void)s2; |
1233 | |
1234 | std::string s3 = entry1.service_name(); |
1235 | (void)s3; |
1236 | |
1237 | std::string s4 = entry1.service_name(alloc); |
1238 | (void)s4; |
1239 | } |
1240 | catch (std::exception&) |
1241 | { |
1242 | } |
1243 | } |
1244 | |
1245 | } // namespace ip_tcp_resolver_entry_compile |
1246 | |
1247 | //------------------------------------------------------------------------------ |
1248 | |
1249 | // ip_tcp_iostream_compile test |
1250 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
1251 | // The following test checks that all public types and member functions on the |
1252 | // class ip::tcp::iostream compile and link correctly. Runtime failures are |
1253 | // ignored. |
1254 | |
1255 | namespace ip_tcp_iostream_compile { |
1256 | |
1257 | void test() |
1258 | { |
1259 | #if !defined(BOOST_ASIO_NO_IOSTREAM) |
1260 | using namespace boost::asio; |
1261 | namespace ip = boost::asio::ip; |
1262 | |
1263 | boost::asio::io_context ioc; |
1264 | boost::asio::ip::tcp::socket sock(ioc); |
1265 | |
1266 | // basic_socket_iostream typedefs. |
1267 | |
1268 | (void)static_cast<ip::tcp::iostream::protocol_type*>(0); |
1269 | (void)static_cast<ip::tcp::iostream::endpoint_type*>(0); |
1270 | (void)static_cast<ip::tcp::iostream::clock_type*>(0); |
1271 | (void)static_cast<ip::tcp::iostream::time_point*>(0); |
1272 | (void)static_cast<ip::tcp::iostream::duration*>(0); |
1273 | (void)static_cast<ip::tcp::iostream::traits_type*>(0); |
1274 | |
1275 | // basic_socket_iostream constructors. |
1276 | |
1277 | ip::tcp::iostream ios1; |
1278 | |
1279 | ip::tcp::iostream ios2(std::move(sock)); |
1280 | |
1281 | ip::tcp::iostream ios3("hostname" , "service" ); |
1282 | |
1283 | // basic_socket_iostream operators. |
1284 | |
1285 | ios1 = ip::tcp::iostream(); |
1286 | |
1287 | ios2 = std::move(ios1); |
1288 | |
1289 | // basic_socket_iostream members. |
1290 | |
1291 | ios1.connect(x: "hostname" , x: "service" ); |
1292 | |
1293 | ios1.close(); |
1294 | |
1295 | (void)static_cast<std::streambuf*>(ios1.rdbuf()); |
1296 | |
1297 | basic_socket<ip::tcp>& sref = ios1.socket(); |
1298 | (void)sref; |
1299 | |
1300 | boost::system::error_code ec = ios1.error(); |
1301 | (void)ec; |
1302 | |
1303 | ip::tcp::iostream::time_point tp = ios1.expiry(); |
1304 | (void)tp; |
1305 | |
1306 | ios1.expires_at(expiry_time: tp); |
1307 | |
1308 | ip::tcp::iostream::duration d = ip::tcp::iostream::duration(); |
1309 | ios1.expires_after(expiry_time: d); |
1310 | |
1311 | // iostream operators. |
1312 | |
1313 | int i = 0; |
1314 | ios1 >> i; |
1315 | ios1 << i; |
1316 | #endif // !defined(BOOST_ASIO_NO_IOSTREAM) |
1317 | } |
1318 | |
1319 | } // namespace ip_tcp_iostream_compile |
1320 | |
1321 | //------------------------------------------------------------------------------ |
1322 | |
1323 | BOOST_ASIO_TEST_SUITE |
1324 | ( |
1325 | "ip/tcp" , |
1326 | BOOST_ASIO_COMPILE_TEST_CASE(ip_tcp_compile::test) |
1327 | BOOST_ASIO_TEST_CASE(ip_tcp_runtime::test) |
1328 | BOOST_ASIO_COMPILE_TEST_CASE(ip_tcp_socket_compile::test) |
1329 | BOOST_ASIO_TEST_CASE(ip_tcp_socket_runtime::test) |
1330 | BOOST_ASIO_COMPILE_TEST_CASE(ip_tcp_acceptor_compile::test) |
1331 | BOOST_ASIO_TEST_CASE(ip_tcp_acceptor_runtime::test) |
1332 | BOOST_ASIO_COMPILE_TEST_CASE(ip_tcp_resolver_compile::test) |
1333 | BOOST_ASIO_COMPILE_TEST_CASE(ip_tcp_resolver_entry_compile::test) |
1334 | BOOST_ASIO_COMPILE_TEST_CASE(ip_tcp_resolver_entry_compile::test) |
1335 | BOOST_ASIO_COMPILE_TEST_CASE(ip_tcp_iostream_compile::test) |
1336 | ) |
1337 | |