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
51namespace ip_tcp_compile {
52
53void 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
87namespace ip_tcp_runtime {
88
89void 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
138namespace ip_tcp_socket_compile {
139
140void connect_handler(const boost::system::error_code&)
141{
142}
143
144void send_handler(const boost::system::error_code&, std::size_t)
145{
146}
147
148void receive_handler(const boost::system::error_code&, std::size_t)
149{
150}
151
152void write_some_handler(const boost::system::error_code&, std::size_t)
153{
154}
155
156void read_some_handler(const boost::system::error_code&, std::size_t)
157{
158}
159
160void 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
464namespace ip_tcp_socket_runtime {
465
466static const char write_data[]
467 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
468
469void 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
477void 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
485void 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
493void 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
501void 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
509void 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
517void 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
629namespace ip_tcp_acceptor_compile {
630
631void accept_handler(const boost::system::error_code&)
632{
633}
634
635void 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
777namespace ip_tcp_acceptor_runtime {
778
779void handle_accept(const boost::system::error_code& err)
780{
781 BOOST_ASIO_CHECK(!err);
782}
783
784void handle_connect(const boost::system::error_code& err)
785{
786 BOOST_ASIO_CHECK(!err);
787}
788
789void 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
859namespace ip_tcp_resolver_compile {
860
861void resolve_handler(const boost::system::error_code&,
862 boost::asio::ip::tcp::resolver::iterator)
863{
864}
865
866void 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
921BOOST_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

source code of boost/libs/asio/test/ip/tcp.cpp