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