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
test()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(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
test()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(no_delay1, ec);
105 BOOST_ASIO_CHECK(!ec);
106
107 ip::tcp::no_delay no_delay2;
108 sock.get_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(no_delay3, ec);
119 BOOST_ASIO_CHECK(!ec);
120
121 ip::tcp::no_delay no_delay4;
122 sock.get_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
connect_handler(const boost::system::error_code &)140 void connect_handler(const boost::system::error_code&)
141 {
142 }
143
send_handler(const boost::system::error_code &,std::size_t)144 void send_handler(const boost::system::error_code&, std::size_t)
145 {
146 }
147
receive_handler(const boost::system::error_code &,std::size_t)148 void receive_handler(const boost::system::error_code&, std::size_t)
149 {
150 }
151
write_some_handler(const boost::system::error_code &,std::size_t)152 void write_some_handler(const boost::system::error_code&, std::size_t)
153 {
154 }
155
read_some_handler(const boost::system::error_code &,std::size_t)156 void read_some_handler(const boost::system::error_code&, std::size_t)
157 {
158 }
159
test()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 = {{
177 boost::asio::buffer(mutable_char_buffer, 10),
178 boost::asio::buffer(mutable_char_buffer + 10, 10) }};
179 array<boost::asio::const_buffer, 2> const_buffers = {{
180 boost::asio::buffer(const_char_buffer, 10),
181 boost::asio::buffer(const_char_buffer + 10, 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(ip::tcp::v4());
233 socket1.open(ip::tcp::v6());
234 socket1.open(ip::tcp::v4(), ec);
235 socket1.open(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(ip::tcp::v4(), native_socket2);
241 ip::tcp::socket::native_handle_type native_socket3
242 = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
243 socket1.assign(ip::tcp::v4(), 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(ip::tcp::endpoint(ip::tcp::v4(), 0));
273 socket1.bind(ip::tcp::endpoint(ip::tcp::v6(), 0));
274 socket1.bind(ip::tcp::endpoint(ip::tcp::v4(), 0), ec);
275 socket1.bind(ip::tcp::endpoint(ip::tcp::v6(), 0), ec);
276
277 socket1.connect(ip::tcp::endpoint(ip::tcp::v4(), 0));
278 socket1.connect(ip::tcp::endpoint(ip::tcp::v6(), 0));
279 socket1.connect(ip::tcp::endpoint(ip::tcp::v4(), 0), ec);
280 socket1.connect(ip::tcp::endpoint(ip::tcp::v6(), 0), ec);
281
282 socket1.async_connect(ip::tcp::endpoint(ip::tcp::v4(), 0),
283 &connect_handler);
284 socket1.async_connect(ip::tcp::endpoint(ip::tcp::v6(), 0),
285 &connect_handler);
286 int i1 = socket1.async_connect(ip::tcp::endpoint(ip::tcp::v4(), 0), lazy);
287 (void)i1;
288 int i2 = socket1.async_connect(ip::tcp::endpoint(ip::tcp::v6(), 0), lazy);
289 (void)i2;
290
291 socket1.set_option(settable_socket_option1);
292 socket1.set_option(settable_socket_option1, ec);
293 socket1.set_option(settable_socket_option2);
294 socket1.set_option(settable_socket_option2, ec);
295 socket1.set_option(settable_socket_option3);
296 socket1.set_option(settable_socket_option3, ec);
297
298 socket1.get_option(gettable_socket_option1);
299 socket1.get_option(gettable_socket_option1, ec);
300 socket1.get_option(gettable_socket_option2);
301 socket1.get_option(gettable_socket_option2, ec);
302 socket1.get_option(gettable_socket_option3);
303 socket1.get_option(gettable_socket_option3, ec);
304
305 socket1.io_control(io_control_command);
306 socket1.io_control(io_control_command, ec);
307
308 bool non_blocking1 = socket1.non_blocking();
309 (void)non_blocking1;
310 socket1.non_blocking(true);
311 socket1.non_blocking(false, ec);
312
313 bool non_blocking2 = socket1.native_non_blocking();
314 (void)non_blocking2;
315 socket1.native_non_blocking(true);
316 socket1.native_non_blocking(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(socket_base::shutdown_both);
325 socket1.shutdown(socket_base::shutdown_both, ec);
326
327 // basic_stream_socket functions.
328
329 socket1.send(buffer(mutable_char_buffer));
330 socket1.send(buffer(const_char_buffer));
331 socket1.send(mutable_buffers);
332 socket1.send(const_buffers);
333 socket1.send(null_buffers());
334 socket1.send(buffer(mutable_char_buffer), in_flags);
335 socket1.send(buffer(const_char_buffer), in_flags);
336 socket1.send(mutable_buffers, in_flags);
337 socket1.send(const_buffers, in_flags);
338 socket1.send(null_buffers(), in_flags);
339 socket1.send(buffer(mutable_char_buffer), in_flags, ec);
340 socket1.send(buffer(const_char_buffer), in_flags, ec);
341 socket1.send(mutable_buffers, in_flags, ec);
342 socket1.send(const_buffers, in_flags, ec);
343 socket1.send(null_buffers(), in_flags, ec);
344
345 socket1.async_send(buffer(mutable_char_buffer), &send_handler);
346 socket1.async_send(buffer(const_char_buffer), &send_handler);
347 socket1.async_send(mutable_buffers, &send_handler);
348 socket1.async_send(const_buffers, &send_handler);
349 socket1.async_send(null_buffers(), &send_handler);
350 socket1.async_send(buffer(mutable_char_buffer), in_flags, &send_handler);
351 socket1.async_send(buffer(const_char_buffer), in_flags, &send_handler);
352 socket1.async_send(mutable_buffers, in_flags, &send_handler);
353 socket1.async_send(const_buffers, in_flags, &send_handler);
354 socket1.async_send(null_buffers(), in_flags, &send_handler);
355 int i3 = socket1.async_send(buffer(mutable_char_buffer), lazy);
356 (void)i3;
357 int i4 = socket1.async_send(buffer(const_char_buffer), lazy);
358 (void)i4;
359 int i5 = socket1.async_send(mutable_buffers, lazy);
360 (void)i5;
361 int i6 = socket1.async_send(const_buffers, lazy);
362 (void)i6;
363 int i7 = socket1.async_send(null_buffers(), lazy);
364 (void)i7;
365 int i8 = socket1.async_send(buffer(mutable_char_buffer), in_flags, lazy);
366 (void)i8;
367 int i9 = socket1.async_send(buffer(const_char_buffer), in_flags, lazy);
368 (void)i9;
369 int i10 = socket1.async_send(mutable_buffers, in_flags, lazy);
370 (void)i10;
371 int i11 = socket1.async_send(const_buffers, in_flags, lazy);
372 (void)i11;
373 int i12 = socket1.async_send(null_buffers(), in_flags, lazy);
374 (void)i12;
375
376 socket1.receive(buffer(mutable_char_buffer));
377 socket1.receive(mutable_buffers);
378 socket1.receive(null_buffers());
379 socket1.receive(buffer(mutable_char_buffer), in_flags);
380 socket1.receive(mutable_buffers, in_flags);
381 socket1.receive(null_buffers(), in_flags);
382 socket1.receive(buffer(mutable_char_buffer), in_flags, ec);
383 socket1.receive(mutable_buffers, in_flags, ec);
384 socket1.receive(null_buffers(), in_flags, ec);
385
386 socket1.async_receive(buffer(mutable_char_buffer), &receive_handler);
387 socket1.async_receive(mutable_buffers, &receive_handler);
388 socket1.async_receive(null_buffers(), &receive_handler);
389 socket1.async_receive(buffer(mutable_char_buffer), in_flags,
390 &receive_handler);
391 socket1.async_receive(mutable_buffers, in_flags, &receive_handler);
392 socket1.async_receive(null_buffers(), in_flags, &receive_handler);
393 int i13 = socket1.async_receive(buffer(mutable_char_buffer), lazy);
394 (void)i13;
395 int i14 = socket1.async_receive(mutable_buffers, lazy);
396 (void)i14;
397 int i15 = socket1.async_receive(null_buffers(), lazy);
398 (void)i15;
399 int i16 = socket1.async_receive(buffer(mutable_char_buffer), in_flags,
400 lazy);
401 (void)i16;
402 int i17 = socket1.async_receive(mutable_buffers, in_flags, lazy);
403 (void)i17;
404 int i18 = socket1.async_receive(null_buffers(), in_flags, lazy);
405 (void)i18;
406
407 socket1.write_some(buffer(mutable_char_buffer));
408 socket1.write_some(buffer(const_char_buffer));
409 socket1.write_some(mutable_buffers);
410 socket1.write_some(const_buffers);
411 socket1.write_some(null_buffers());
412 socket1.write_some(buffer(mutable_char_buffer), ec);
413 socket1.write_some(buffer(const_char_buffer), ec);
414 socket1.write_some(mutable_buffers, ec);
415 socket1.write_some(const_buffers, ec);
416 socket1.write_some(null_buffers(), ec);
417
418 socket1.async_write_some(buffer(mutable_char_buffer), &write_some_handler);
419 socket1.async_write_some(buffer(const_char_buffer), &write_some_handler);
420 socket1.async_write_some(mutable_buffers, &write_some_handler);
421 socket1.async_write_some(const_buffers, &write_some_handler);
422 socket1.async_write_some(null_buffers(), &write_some_handler);
423 int i19 = socket1.async_write_some(buffer(mutable_char_buffer), lazy);
424 (void)i19;
425 int i20 = socket1.async_write_some(buffer(const_char_buffer), lazy);
426 (void)i20;
427 int i21 = socket1.async_write_some(mutable_buffers, lazy);
428 (void)i21;
429 int i22 = socket1.async_write_some(const_buffers, lazy);
430 (void)i22;
431 int i23 = socket1.async_write_some(null_buffers(), lazy);
432 (void)i23;
433
434 socket1.read_some(buffer(mutable_char_buffer));
435 socket1.read_some(mutable_buffers);
436 socket1.read_some(null_buffers());
437 socket1.read_some(buffer(mutable_char_buffer), ec);
438 socket1.read_some(mutable_buffers, ec);
439 socket1.read_some(null_buffers(), ec);
440
441 socket1.async_read_some(buffer(mutable_char_buffer), &read_some_handler);
442 socket1.async_read_some(mutable_buffers, &read_some_handler);
443 socket1.async_read_some(null_buffers(), &read_some_handler);
444 int i24 = socket1.async_read_some(buffer(mutable_char_buffer), lazy);
445 (void)i24;
446 int i25 = socket1.async_read_some(mutable_buffers, lazy);
447 (void)i25;
448 int i26 = socket1.async_read_some(null_buffers(), 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
handle_read_noop(const boost::system::error_code & err,size_t bytes_transferred,bool * called)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
handle_write_noop(const boost::system::error_code & err,size_t bytes_transferred,bool * called)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
handle_read(const boost::system::error_code & err,size_t bytes_transferred,bool * called)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
handle_write(const boost::system::error_code & err,size_t bytes_transferred,bool * called)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
handle_read_cancel(const boost::system::error_code & err,size_t bytes_transferred,bool * called)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
handle_read_eof(const boost::system::error_code & err,size_t bytes_transferred,bool * called)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
test()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(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(server_endpoint);
541 acceptor.accept(server_side_socket);
542
543 // No-op read.
544
545 bool read_noop_completed = false;
546 client_side_socket.async_read_some(
547 boost::asio::mutable_buffers_1(0, 0),
548 bindns::bind(handle_read_noop,
549 _1, _2, &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 boost::asio::const_buffers_1(0, 0),
559 bindns::bind(handle_write_noop,
560 _1, _2, &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(client_side_socket,
571 boost::asio::buffer(read_buffer),
572 bindns::bind(handle_read,
573 _1, _2, &read_completed));
574
575 bool write_completed = false;
576 boost::asio::async_write(server_side_socket,
577 boost::asio::buffer(write_data),
578 bindns::bind(handle_write,
579 _1, _2, &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(server_side_socket,
591 boost::asio::buffer(read_buffer),
592 bindns::bind(handle_read_cancel,
593 _1, _2, &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(client_side_socket,
609 boost::asio::buffer(read_buffer),
610 bindns::bind(handle_read_eof,
611 _1, _2, &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
accept_handler(const boost::system::error_code &)631 void accept_handler(const boost::system::error_code&)
632 {
633 }
634
test()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(ip::tcp::v4());
687 acceptor1.open(ip::tcp::v6());
688 acceptor1.open(ip::tcp::v4(), ec);
689 acceptor1.open(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(ip::tcp::v4(), native_acceptor2);
695 ip::tcp::acceptor::native_handle_type native_acceptor3
696 = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
697 acceptor1.assign(ip::tcp::v4(), 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(ip::tcp::endpoint(ip::tcp::v4(), 0));
717 acceptor1.bind(ip::tcp::endpoint(ip::tcp::v6(), 0));
718 acceptor1.bind(ip::tcp::endpoint(ip::tcp::v4(), 0), ec);
719 acceptor1.bind(ip::tcp::endpoint(ip::tcp::v6(), 0), ec);
720
721 acceptor1.set_option(settable_socket_option1);
722 acceptor1.set_option(settable_socket_option1, ec);
723 acceptor1.set_option(settable_socket_option2);
724 acceptor1.set_option(settable_socket_option2, ec);
725 acceptor1.set_option(settable_socket_option3);
726 acceptor1.set_option(settable_socket_option3, ec);
727
728 acceptor1.get_option(gettable_socket_option1);
729 acceptor1.get_option(gettable_socket_option1, ec);
730 acceptor1.get_option(gettable_socket_option2);
731 acceptor1.get_option(gettable_socket_option2, ec);
732 acceptor1.get_option(gettable_socket_option3);
733 acceptor1.get_option(gettable_socket_option3, ec);
734
735 acceptor1.io_control(io_control_command);
736 acceptor1.io_control(io_control_command, ec);
737
738 bool non_blocking1 = acceptor1.non_blocking();
739 (void)non_blocking1;
740 acceptor1.non_blocking(true);
741 acceptor1.non_blocking(false, ec);
742
743 bool non_blocking2 = acceptor1.native_non_blocking();
744 (void)non_blocking2;
745 acceptor1.native_non_blocking(true);
746 acceptor1.native_non_blocking(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_socket);
752 acceptor1.accept(peer_socket, ec);
753 acceptor1.accept(peer_socket, peer_endpoint);
754 acceptor1.accept(peer_socket, peer_endpoint, ec);
755
756 acceptor1.async_accept(peer_socket, &accept_handler);
757 acceptor1.async_accept(peer_socket, peer_endpoint, &accept_handler);
758 int i1 = acceptor1.async_accept(peer_socket, lazy);
759 (void)i1;
760 int i2 = acceptor1.async_accept(peer_socket, peer_endpoint, 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
handle_accept(const boost::system::error_code & err)779 void handle_accept(const boost::system::error_code& err)
780 {
781 BOOST_ASIO_CHECK(!err);
782 }
783
handle_connect(const boost::system::error_code & err)784 void handle_connect(const boost::system::error_code& err)
785 {
786 BOOST_ASIO_CHECK(!err);
787 }
788
test()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(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(server_endpoint);
804 acceptor.accept(server_side_socket);
805
806 client_side_socket.close();
807 server_side_socket.close();
808
809 client_side_socket.connect(server_endpoint);
810 ip::tcp::endpoint client_endpoint;
811 acceptor.accept(server_side_socket, 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(server_side_socket, &handle_accept);
829 client_side_socket.async_connect(server_endpoint, &handle_connect);
830
831 ios.run();
832
833 client_side_socket.close();
834 server_side_socket.close();
835
836 acceptor.async_accept(server_side_socket, client_endpoint, &handle_accept);
837 client_side_socket.async_connect(server_endpoint, &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
resolve_handler(const boost::system::error_code &,boost::asio::ip::tcp::resolver::iterator)861 void resolve_handler(const boost::system::error_code&,
862 boost::asio::ip::tcp::resolver::iterator)
863 {
864 }
865
test()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, &resolve_handler);
905 int i1 = resolver.async_resolve(q, lazy);
906 (void)i1;
907
908 resolver.async_resolve(e, &resolve_handler);
909 int i2 = resolver.async_resolve(e, 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