diff --git a/asio/boostify.pl b/asio/boostify.pl index 74c6c17fab..a52b886633 100755 --- a/asio/boostify.pl +++ b/asio/boostify.pl @@ -295,6 +295,12 @@ sub copy_source_file $line =~ s/asio::/boost::asio::/g if !$is_xsl; print_line($output, $line, $from, $lineno); } + elsif ($line =~ /std::system_error/) + { + $line =~ s/std::system_error/boost::system::system_error/g; + $line =~ s/asio::/boost::asio::/g if !$is_xsl; + print_line($output, $line, $from, $lineno); + } elsif ($line =~ /ec\.assign\(0, ec\.category\(\)\)/) { $line =~ s/ec\.assign\(0, ec\.category\(\)\)/ec = boost::system::error_code()/g; @@ -555,56 +561,23 @@ sub copy_properties_tests sub copy_examples { my @dirs = ( - "src/examples/cpp03/allocation", - "src/examples/cpp03/buffers", - "src/examples/cpp03/chat", - "src/examples/cpp03/echo", - "src/examples/cpp03/fork", - "src/examples/cpp03/http/client", - "src/examples/cpp03/http/doc_root", - "src/examples/cpp03/http/server", - "src/examples/cpp03/http/server2", - "src/examples/cpp03/http/server3", - "src/examples/cpp03/http/server4", - "src/examples/cpp03/icmp", - "src/examples/cpp03/invocation", - "src/examples/cpp03/iostreams", - "src/examples/cpp03/local", - "src/examples/cpp03/multicast", - "src/examples/cpp03/nonblocking", - "src/examples/cpp03/porthopper", - "src/examples/cpp03/serialization", - "src/examples/cpp03/services", - "src/examples/cpp03/socks4", - "src/examples/cpp03/spawn", - "src/examples/cpp03/ssl", - "src/examples/cpp03/timeouts", - "src/examples/cpp03/timers", - "src/examples/cpp03/tutorial", - "src/examples/cpp03/tutorial/daytime1", - "src/examples/cpp03/tutorial/daytime2", - "src/examples/cpp03/tutorial/daytime3", - "src/examples/cpp03/tutorial/daytime4", - "src/examples/cpp03/tutorial/daytime5", - "src/examples/cpp03/tutorial/daytime6", - "src/examples/cpp03/tutorial/daytime7", - "src/examples/cpp03/tutorial/timer1", - "src/examples/cpp03/tutorial/timer2", - "src/examples/cpp03/tutorial/timer3", - "src/examples/cpp03/tutorial/timer4", - "src/examples/cpp03/tutorial/timer5", - "src/examples/cpp03/windows", "src/examples/cpp11/allocation", "src/examples/cpp11/buffers", "src/examples/cpp11/chat", "src/examples/cpp11/deferred", "src/examples/cpp11/echo", "src/examples/cpp11/executors", - "src/examples/cpp11/fork", "src/examples/cpp11/files", + "src/examples/cpp11/fork", "src/examples/cpp11/futures", "src/examples/cpp11/handler_tracking", + "src/examples/cpp11/http/client", + "src/examples/cpp11/http/doc_root", "src/examples/cpp11/http/server", + "src/examples/cpp11/http/server2", + "src/examples/cpp11/http/server3", + "src/examples/cpp11/http/server4", + "src/examples/cpp11/icmp", "src/examples/cpp11/invocation", "src/examples/cpp11/iostreams", "src/examples/cpp11/local", @@ -612,12 +585,29 @@ sub copy_examples "src/examples/cpp11/nonblocking", "src/examples/cpp11/operations", "src/examples/cpp11/parallel_group", + "src/examples/cpp11/porthopper", + "src/examples/cpp11/serialization", + "src/examples/cpp11/services", "src/examples/cpp11/socks4", "src/examples/cpp11/spawn", "src/examples/cpp11/ssl", "src/examples/cpp11/timeouts", "src/examples/cpp11/timers", + "src/examples/cpp11/tutorial", + "src/examples/cpp11/tutorial/daytime1", + "src/examples/cpp11/tutorial/daytime2", + "src/examples/cpp11/tutorial/daytime3", + "src/examples/cpp11/tutorial/daytime4", + "src/examples/cpp11/tutorial/daytime5", + "src/examples/cpp11/tutorial/daytime6", + "src/examples/cpp11/tutorial/daytime7", + "src/examples/cpp11/tutorial/timer1", + "src/examples/cpp11/tutorial/timer2", + "src/examples/cpp11/tutorial/timer3", + "src/examples/cpp11/tutorial/timer4", + "src/examples/cpp11/tutorial/timer5", "src/examples/cpp11/type_erasure", + "src/examples/cpp11/windows", "src/examples/cpp14/deferred", "src/examples/cpp14/echo", "src/examples/cpp14/executors", diff --git a/asio/configure.ac b/asio/configure.ac index 3908366c2f..0fbbdbd146 100644 --- a/asio/configure.ac +++ b/asio/configure.ac @@ -252,7 +252,6 @@ AC_OUTPUT([ src/Makefile src/tests/Makefile src/tests/properties/Makefile - src/examples/cpp03/Makefile src/examples/cpp11/Makefile src/examples/cpp14/Makefile src/examples/cpp17/Makefile diff --git a/asio/release.pl b/asio/release.pl index 9e7068da39..fb9572e294 100755 --- a/asio/release.pl +++ b/asio/release.pl @@ -201,27 +201,6 @@ sub build_asio_doc system("cp -vR src/doc/html/* doc"); } -sub build_example_diffs -{ - my @cpp11_files = `find src/examples/cpp11 -type f -name "*.*pp"`; - foreach my $cpp11_file (@cpp11_files) - { - chomp($cpp11_file); - - my $cpp03_file = $cpp11_file; - $cpp03_file =~ s/\/cpp11\//\/cpp03\//; - my $output_diff = $cpp11_file; - $output_diff =~ s/src\/examples\/cpp11\///g; - my ($output_diff_name, $output_dir) = fileparse($output_diff); - my $output_html = $output_diff . ".html"; - - mkpath("doc/examples/diffs/$output_dir"); - system("diff -U1000000 $cpp03_file $cpp11_file > doc/examples/diffs/$output_diff"); - system("cd doc/examples/diffs && diff2html.py -i $output_diff -o $output_html"); - unlink("doc/examples/diffs/$output_diff"); - } -} - sub make_asio_packages { our $asio_name; @@ -428,7 +407,6 @@ sub make_boost_asio_packages if ($package_asio) { build_asio_doc(); - build_example_diffs(); make_asio_packages(); } diff --git a/asio/src/Makefile.am b/asio/src/Makefile.am index 0345f094f8..587bb4935e 100644 --- a/asio/src/Makefile.am +++ b/asio/src/Makefile.am @@ -1,7 +1,3 @@ -if !STANDALONE -EXAMPLES_CPP03 = examples/cpp03 -endif - if HAVE_CXX11 EXAMPLES_CPP11 = examples/cpp11 endif @@ -19,7 +15,6 @@ EXAMPLES_CPP20 = examples/cpp20 endif SUBDIRS = \ - $(EXAMPLES_CPP03) \ $(EXAMPLES_CPP11) \ $(EXAMPLES_CPP14) \ $(EXAMPLES_CPP17) \ @@ -27,7 +22,6 @@ SUBDIRS = \ tests DIST_SUBDIRS = \ - examples/cpp03 \ examples/cpp11 \ examples/cpp14 \ examples/cpp17 \ diff --git a/asio/src/Makefile.mgw b/asio/src/Makefile.mgw index a88a7c1c78..2d31a040da 100644 --- a/asio/src/Makefile.mgw +++ b/asio/src/Makefile.mgw @@ -162,54 +162,54 @@ UNIT_TEST_EXES = \ tests/unit/write.exe \ tests/unit/write_at.exe -CPP03_EXAMPLE_EXES = \ - examples/cpp03/allocation/server.exe \ - examples/cpp03/buffers/reference_counted.exe \ - examples/cpp03/chat/chat_client.exe \ - examples/cpp03/chat/chat_server.exe \ - examples/cpp03/echo/async_tcp_echo_server.exe \ - examples/cpp03/echo/async_udp_echo_server.exe \ - examples/cpp03/echo/blocking_tcp_echo_client.exe \ - examples/cpp03/echo/blocking_tcp_echo_server.exe \ - examples/cpp03/echo/blocking_udp_echo_client.exe \ - examples/cpp03/echo/blocking_udp_echo_server.exe \ - examples/cpp03/http/client/async_client.exe \ - examples/cpp03/http/client/sync_client.exe \ - examples/cpp03/http/server/http_server.exe \ - examples/cpp03/http/server2/http_server.exe \ - examples/cpp03/http/server3/http_server.exe \ - examples/cpp03/http/server4/http_server.exe \ - examples/cpp03/icmp/ping.exe \ - examples/cpp03/invocation/prioritised_handlers.exe \ - examples/cpp03/iostreams/daytime_client.exe \ - examples/cpp03/iostreams/daytime_server.exe \ - examples/cpp03/iostreams/http_client.exe \ - examples/cpp03/multicast/receiver.exe \ - examples/cpp03/multicast/sender.exe \ - examples/cpp03/nonblocking/third_party_lib.exe \ - examples/cpp03/porthopper/client.exe \ - examples/cpp03/porthopper/server.exe \ - examples/cpp03/services/daytime_client.exe \ - examples/cpp03/socks4/sync_client.exe \ - examples/cpp03/timeouts/async_tcp_client.exe \ - examples/cpp03/timeouts/blocking_tcp_client.exe \ - examples/cpp03/timeouts/blocking_token_tcp_client.exe \ - examples/cpp03/timeouts/blocking_udp_client.exe \ - examples/cpp03/timeouts/server.exe \ - examples/cpp03/timers/time_t_timer.exe \ - examples/cpp03/tutorial/timer1/timer.exe \ - examples/cpp03/tutorial/timer2/timer.exe \ - examples/cpp03/tutorial/timer3/timer.exe \ - examples/cpp03/tutorial/timer4/timer.exe \ - examples/cpp03/tutorial/timer5/timer.exe \ - examples/cpp03/tutorial/daytime1/client.exe \ - examples/cpp03/tutorial/daytime2/server.exe \ - examples/cpp03/tutorial/daytime3/server.exe \ - examples/cpp03/tutorial/daytime4/client.exe \ - examples/cpp03/tutorial/daytime5/server.exe \ - examples/cpp03/tutorial/daytime6/server.exe \ - examples/cpp03/tutorial/daytime7/server.exe \ - examples/cpp03/windows/transmit_file.exe +CPP11_EXAMPLE_EXES = \ + examples/cpp11/allocation/server.exe \ + examples/cpp11/buffers/reference_counted.exe \ + examples/cpp11/chat/chat_client.exe \ + examples/cpp11/chat/chat_server.exe \ + examples/cpp11/echo/async_tcp_echo_server.exe \ + examples/cpp11/echo/async_udp_echo_server.exe \ + examples/cpp11/echo/blocking_tcp_echo_client.exe \ + examples/cpp11/echo/blocking_tcp_echo_server.exe \ + examples/cpp11/echo/blocking_udp_echo_client.exe \ + examples/cpp11/echo/blocking_udp_echo_server.exe \ + examples/cpp11/http/client/async_client.exe \ + examples/cpp11/http/client/sync_client.exe \ + examples/cpp11/http/server/http_server.exe \ + examples/cpp11/http/server2/http_server.exe \ + examples/cpp11/http/server3/http_server.exe \ + examples/cpp11/http/server4/http_server.exe \ + examples/cpp11/icmp/ping.exe \ + examples/cpp11/invocation/prioritised_handlers.exe \ + examples/cpp11/iostreams/daytime_client.exe \ + examples/cpp11/iostreams/daytime_server.exe \ + examples/cpp11/iostreams/http_client.exe \ + examples/cpp11/multicast/receiver.exe \ + examples/cpp11/multicast/sender.exe \ + examples/cpp11/nonblocking/third_party_lib.exe \ + examples/cpp11/porthopper/client.exe \ + examples/cpp11/porthopper/server.exe \ + examples/cpp11/services/daytime_client.exe \ + examples/cpp11/socks4/sync_client.exe \ + examples/cpp11/timeouts/async_tcp_client.exe \ + examples/cpp11/timeouts/blocking_tcp_client.exe \ + examples/cpp11/timeouts/blocking_token_tcp_client.exe \ + examples/cpp11/timeouts/blocking_udp_client.exe \ + examples/cpp11/timeouts/server.exe \ + examples/cpp11/timers/time_t_timer.exe \ + examples/cpp11/tutorial/timer1/timer.exe \ + examples/cpp11/tutorial/timer2/timer.exe \ + examples/cpp11/tutorial/timer3/timer.exe \ + examples/cpp11/tutorial/timer4/timer.exe \ + examples/cpp11/tutorial/timer5/timer.exe \ + examples/cpp11/tutorial/daytime1/client.exe \ + examples/cpp11/tutorial/daytime2/server.exe \ + examples/cpp11/tutorial/daytime3/server.exe \ + examples/cpp11/tutorial/daytime4/client.exe \ + examples/cpp11/tutorial/daytime5/server.exe \ + examples/cpp11/tutorial/daytime6/server.exe \ + examples/cpp11/tutorial/daytime7/server.exe \ + examples/cpp11/windows/transmit_file.exe ifdef STANDALONE all: \ @@ -249,41 +249,41 @@ $(UNIT_TEST_EXES): %.exe: %.o $(PERFORMANCE_TEST_EXES) $(EXAMPLE_EXES): %.exe: %.o g++ -o$@ $(LDFLAGS) $< $(LIBS) -examples/cpp03/http/server/http_server.exe: \ - examples/cpp03/http/server/connection.o \ - examples/cpp03/http/server/connection_manager.o \ - examples/cpp03/http/server/main.o \ - examples/cpp03/http/server/mime_types.o \ - examples/cpp03/http/server/reply.o \ - examples/cpp03/http/server/request_handler.o \ - examples/cpp03/http/server/request_parser.o \ - examples/cpp03/http/server/server.o +examples/cpp11/http/server/http_server.exe: \ + examples/cpp11/http/server/connection.o \ + examples/cpp11/http/server/connection_manager.o \ + examples/cpp11/http/server/main.o \ + examples/cpp11/http/server/mime_types.o \ + examples/cpp11/http/server/reply.o \ + examples/cpp11/http/server/request_handler.o \ + examples/cpp11/http/server/request_parser.o \ + examples/cpp11/http/server/server.o g++ -o$@ $(LDFLAGS) $^ $(LIBS) -examples/cpp03/http/server2/http_server.exe: \ - examples/cpp03/http/server2/connection.o \ - examples/cpp03/http/server2/io_context_pool.o \ - examples/cpp03/http/server2/main.o \ - examples/cpp03/http/server2/mime_types.o \ - examples/cpp03/http/server2/reply.o \ - examples/cpp03/http/server2/request_handler.o \ - examples/cpp03/http/server2/request_parser.o \ - examples/cpp03/http/server2/server.o +examples/cpp11/http/server2/http_server.exe: \ + examples/cpp11/http/server2/connection.o \ + examples/cpp11/http/server2/io_context_pool.o \ + examples/cpp11/http/server2/main.o \ + examples/cpp11/http/server2/mime_types.o \ + examples/cpp11/http/server2/reply.o \ + examples/cpp11/http/server2/request_handler.o \ + examples/cpp11/http/server2/request_parser.o \ + examples/cpp11/http/server2/server.o g++ -o$@ $(LDFLAGS) $^ $(LIBS) -examples/cpp03/http/server3/http_server.exe: \ - examples/cpp03/http/server3/connection.o \ - examples/cpp03/http/server3/main.o \ - examples/cpp03/http/server3/mime_types.o \ - examples/cpp03/http/server3/reply.o \ - examples/cpp03/http/server3/request_handler.o \ - examples/cpp03/http/server3/request_parser.o \ - examples/cpp03/http/server3/server.o +examples/cpp11/http/server3/http_server.exe: \ + examples/cpp11/http/server3/connection.o \ + examples/cpp11/http/server3/main.o \ + examples/cpp11/http/server3/mime_types.o \ + examples/cpp11/http/server3/reply.o \ + examples/cpp11/http/server3/request_handler.o \ + examples/cpp11/http/server3/request_parser.o \ + examples/cpp11/http/server3/server.o g++ -o$@ $(LDFLAGS) $^ $(LIBS) -examples/cpp03/services/daytime_client.exe: \ - examples/cpp03/services/daytime_client.o \ - examples/cpp03/services/logger_service.o +examples/cpp11/services/daytime_client.exe: \ + examples/cpp11/services/daytime_client.o \ + examples/cpp11/services/logger_service.o g++ -o$@ $(LDFLAGS) $^ $(LIBS) .cpp.o: diff --git a/asio/src/Makefile.msc b/asio/src/Makefile.msc index baec16dcb2..868c4e1187 100644 --- a/asio/src/Makefile.msc +++ b/asio/src/Makefile.msc @@ -271,54 +271,54 @@ UNIT_TEST_EXES = \ tests\unit\write.exe \ tests\unit\write_at.exe -CPP03_EXAMPLE_EXES = \ - examples\cpp03\allocation\server.exe \ - examples\cpp03\buffers\reference_counted.exe \ - examples\cpp03\chat\chat_client.exe \ - examples\cpp03\chat\chat_server.exe \ - examples\cpp03\echo\async_tcp_echo_server.exe \ - examples\cpp03\echo\async_udp_echo_server.exe \ - examples\cpp03\echo\blocking_tcp_echo_client.exe \ - examples\cpp03\echo\blocking_tcp_echo_server.exe \ - examples\cpp03\echo\blocking_udp_echo_client.exe \ - examples\cpp03\echo\blocking_udp_echo_server.exe \ - examples\cpp03\http\client\async_client.exe \ - examples\cpp03\http\client\sync_client.exe \ - examples\cpp03\http\server\http_server.exe \ - examples\cpp03\http\server2\http_server.exe \ - examples\cpp03\http\server3\http_server.exe \ - examples\cpp03\http\server4\http_server.exe \ - examples\cpp03\icmp\ping.exe \ - examples\cpp03\invocation\prioritised_handlers.exe \ - examples\cpp03\iostreams\daytime_client.exe \ - examples\cpp03\iostreams\daytime_server.exe \ - examples\cpp03\iostreams\http_client.exe \ - examples\cpp03\multicast\receiver.exe \ - examples\cpp03\multicast\sender.exe \ - examples\cpp03\nonblocking\third_party_lib.exe \ - examples\cpp03\porthopper\client.exe \ - examples\cpp03\porthopper\server.exe \ - examples\cpp03\services\daytime_client.exe \ - examples\cpp03\socks4\sync_client.exe \ - examples\cpp03\timeouts\async_tcp_client.exe \ - examples\cpp03\timeouts\blocking_tcp_client.exe \ - examples\cpp03\timeouts\blocking_token_tcp_client.exe \ - examples\cpp03\timeouts\blocking_udp_client.exe \ - examples\cpp03\timeouts\server.exe \ - examples\cpp03\timers\time_t_timer.exe \ - examples\cpp03\tutorial\timer1\timer.exe \ - examples\cpp03\tutorial\timer2\timer.exe \ - examples\cpp03\tutorial\timer3\timer.exe \ - examples\cpp03\tutorial\timer4\timer.exe \ - examples\cpp03\tutorial\timer5\timer.exe \ - examples\cpp03\tutorial\daytime1\client.exe \ - examples\cpp03\tutorial\daytime2\server.exe \ - examples\cpp03\tutorial\daytime3\server.exe \ - examples\cpp03\tutorial\daytime4\client.exe \ - examples\cpp03\tutorial\daytime5\server.exe \ - examples\cpp03\tutorial\daytime6\server.exe \ - examples\cpp03\tutorial\daytime7\server.exe \ - examples\cpp03\windows\transmit_file.exe +CPP11_EXAMPLE_EXES = \ + examples\cpp11\allocation\server.exe \ + examples\cpp11\buffers\reference_counted.exe \ + examples\cpp11\chat\chat_client.exe \ + examples\cpp11\chat\chat_server.exe \ + examples\cpp11\echo\async_tcp_echo_server.exe \ + examples\cpp11\echo\async_udp_echo_server.exe \ + examples\cpp11\echo\blocking_tcp_echo_client.exe \ + examples\cpp11\echo\blocking_tcp_echo_server.exe \ + examples\cpp11\echo\blocking_udp_echo_client.exe \ + examples\cpp11\echo\blocking_udp_echo_server.exe \ + examples\cpp11\http\client\async_client.exe \ + examples\cpp11\http\client\sync_client.exe \ + examples\cpp11\http\server\http_server.exe \ + examples\cpp11\http\server2\http_server.exe \ + examples\cpp11\http\server3\http_server.exe \ + examples\cpp11\http\server4\http_server.exe \ + examples\cpp11\icmp\ping.exe \ + examples\cpp11\invocation\prioritised_handlers.exe \ + examples\cpp11\iostreams\daytime_client.exe \ + examples\cpp11\iostreams\daytime_server.exe \ + examples\cpp11\iostreams\http_client.exe \ + examples\cpp11\multicast\receiver.exe \ + examples\cpp11\multicast\sender.exe \ + examples\cpp11\nonblocking\third_party_lib.exe \ + examples\cpp11\porthopper\client.exe \ + examples\cpp11\porthopper\server.exe \ + examples\cpp11\services\daytime_client.exe \ + examples\cpp11\socks4\sync_client.exe \ + examples\cpp11\timeouts\async_tcp_client.exe \ + examples\cpp11\timeouts\blocking_tcp_client.exe \ + examples\cpp11\timeouts\blocking_token_tcp_client.exe \ + examples\cpp11\timeouts\blocking_udp_client.exe \ + examples\cpp11\timeouts\server.exe \ + examples\cpp11\timers\time_t_timer.exe \ + examples\cpp11\tutorial\timer1\timer.exe \ + examples\cpp11\tutorial\timer2\timer.exe \ + examples\cpp11\tutorial\timer3\timer.exe \ + examples\cpp11\tutorial\timer4\timer.exe \ + examples\cpp11\tutorial\timer5\timer.exe \ + examples\cpp11\tutorial\daytime1\client.exe \ + examples\cpp11\tutorial\daytime2\server.exe \ + examples\cpp11\tutorial\daytime3\server.exe \ + examples\cpp11\tutorial\daytime4\client.exe \ + examples\cpp11\tutorial\daytime5\server.exe \ + examples\cpp11\tutorial\daytime6\server.exe \ + examples\cpp11\tutorial\daytime7\server.exe \ + examples\cpp11\windows\transmit_file.exe SSL_UNIT_TEST_EXES = \ tests\unit\ssl\basic_context.exe \ @@ -331,8 +331,8 @@ SSL_UNIT_TEST_EXES = \ tests\unit\ssl\stream_service.exe SSL_EXAMPLE_EXES = \ - examples\cpp03\ssl\client.exe \ - examples\cpp03\ssl\server.exe + examples\cpp11\ssl\client.exe \ + examples\cpp11\ssl\server.exe !ifdef SEPARATE_COMPILATION all: asio.lib @@ -392,88 +392,88 @@ tests\unit\unit_test.obj: tests\unit\unit_test.cpp {tests\unit\windows}.cpp{tests\unit\windows}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref -{examples\cpp03\allocation}.cpp{examples\cpp03\allocation}.exe: +{examples\cpp11\allocation}.cpp{examples\cpp11\allocation}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref -{examples\cpp03\buffers}.cpp{examples\cpp03\buffers}.exe: +{examples\cpp11\buffers}.cpp{examples\cpp11\buffers}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref -{examples\cpp03\chat}.cpp{examples\cpp03\chat}.exe: +{examples\cpp11\chat}.cpp{examples\cpp11\chat}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref -{examples\cpp03\echo}.cpp{examples\cpp03\echo}.exe: +{examples\cpp11\echo}.cpp{examples\cpp11\echo}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref -{examples\cpp03\http\client}.cpp{examples\cpp03\http\client}.exe: +{examples\cpp11\http\client}.cpp{examples\cpp11\http\client}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref -{examples\cpp03\icmp}.cpp{examples\cpp03\icmp}.exe: +{examples\cpp11\icmp}.cpp{examples\cpp11\icmp}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref -{examples\cpp03\invocation}.cpp{examples\cpp03\invocation}.exe: +{examples\cpp11\invocation}.cpp{examples\cpp11\invocation}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref -{examples\cpp03\iostreams}.cpp{examples\cpp03\iostreams}.exe: +{examples\cpp11\iostreams}.cpp{examples\cpp11\iostreams}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref -{examples\cpp03\multicast}.cpp{examples\cpp03\multicast}.exe: +{examples\cpp11\multicast}.cpp{examples\cpp11\multicast}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref -{examples\cpp03\nonblocking}.cpp{examples\cpp03\nonblocking}.exe: +{examples\cpp11\nonblocking}.cpp{examples\cpp11\nonblocking}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref -{examples\cpp03\porthopper}.cpp{examples\cpp03\porthopper}.exe: +{examples\cpp11\porthopper}.cpp{examples\cpp11\porthopper}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref -{examples\cpp03\socks4}.cpp{examples\cpp03\socks4}.exe: +{examples\cpp11\socks4}.cpp{examples\cpp11\socks4}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref -{examples\cpp03\ssl}.cpp{examples\cpp03\ssl}.exe: +{examples\cpp11\ssl}.cpp{examples\cpp11\ssl}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(SSL_CXXFLAGS) $(DEFINES) $< $(SSL_LIBS) $(LIBS) -link -opt:ref -{examples\cpp03\timeouts}.cpp{examples\cpp03\timeouts}.exe: +{examples\cpp11\timeouts}.cpp{examples\cpp11\timeouts}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref -{examples\cpp03\timers}.cpp{examples\cpp03\timers}.exe: +{examples\cpp11\timers}.cpp{examples\cpp11\timers}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref -{examples\cpp03\tutorial\timer1}.cpp{examples\cpp03\tutorial\timer1}.exe: +{examples\cpp11\tutorial\timer1}.cpp{examples\cpp11\tutorial\timer1}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref -{examples\cpp03\tutorial\timer2}.cpp{examples\cpp03\tutorial\timer2}.exe: +{examples\cpp11\tutorial\timer2}.cpp{examples\cpp11\tutorial\timer2}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref -{examples\cpp03\tutorial\timer3}.cpp{examples\cpp03\tutorial\timer3}.exe: +{examples\cpp11\tutorial\timer3}.cpp{examples\cpp11\tutorial\timer3}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref -{examples\cpp03\tutorial\timer4}.cpp{examples\cpp03\tutorial\timer4}.exe: +{examples\cpp11\tutorial\timer4}.cpp{examples\cpp11\tutorial\timer4}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref -{examples\cpp03\tutorial\timer5}.cpp{examples\cpp03\tutorial\timer5}.exe: +{examples\cpp11\tutorial\timer5}.cpp{examples\cpp11\tutorial\timer5}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref -{examples\cpp03\tutorial\daytime1}.cpp{examples\cpp03\tutorial\daytime1}.exe: +{examples\cpp11\tutorial\daytime1}.cpp{examples\cpp11\tutorial\daytime1}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref -{examples\cpp03\tutorial\daytime2}.cpp{examples\cpp03\tutorial\daytime2}.exe: +{examples\cpp11\tutorial\daytime2}.cpp{examples\cpp11\tutorial\daytime2}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref -{examples\cpp03\tutorial\daytime3}.cpp{examples\cpp03\tutorial\daytime3}.exe: +{examples\cpp11\tutorial\daytime3}.cpp{examples\cpp11\tutorial\daytime3}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref -{examples\cpp03\tutorial\daytime4}.cpp{examples\cpp03\tutorial\daytime4}.exe: +{examples\cpp11\tutorial\daytime4}.cpp{examples\cpp11\tutorial\daytime4}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref -{examples\cpp03\tutorial\daytime5}.cpp{examples\cpp03\tutorial\daytime5}.exe: +{examples\cpp11\tutorial\daytime5}.cpp{examples\cpp11\tutorial\daytime5}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref -{examples\cpp03\tutorial\daytime6}.cpp{examples\cpp03\tutorial\daytime6}.exe: +{examples\cpp11\tutorial\daytime6}.cpp{examples\cpp11\tutorial\daytime6}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref -{examples\cpp03\tutorial\daytime7}.cpp{examples\cpp03\tutorial\daytime7}.exe: +{examples\cpp11\tutorial\daytime7}.cpp{examples\cpp11\tutorial\daytime7}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref -{examples\cpp03\windows}.cpp{examples\cpp03\windows}.exe: +{examples\cpp11\windows}.cpp{examples\cpp11\windows}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref {examples\cpp11\executors}.cpp{examples\cpp11\executors}.exe: @@ -485,51 +485,51 @@ tests\unit\unit_test.obj: tests\unit\unit_test.cpp {examples\cpp14\operations}.cpp{examples\cpp14\operations}.exe: cl -Fe$@ -Fo$(<:.cpp=.obj) $(CXXFLAGS) $(DEFINES) $< $(LIBS) -link -opt:ref -examples\cpp03\http\server\http_server.exe: \ - examples\cpp03\http\server\connection.cpp \ - examples\cpp03\http\server\connection_manager.cpp \ - examples\cpp03\http\server\main.cpp \ - examples\cpp03\http\server\mime_types.cpp \ - examples\cpp03\http\server\reply.cpp \ - examples\cpp03\http\server\request_handler.cpp \ - examples\cpp03\http\server\request_parser.cpp \ - examples\cpp03\http\server\server.cpp - cl -Fe$@ -Foexamples\cpp03\http\server\ $(CXXFLAGS) $(DEFINES) $** $(LIBS) -link -opt:ref - -examples\cpp03\http\server2\http_server.exe: \ - examples\cpp03\http\server2\connection.cpp \ - examples\cpp03\http\server2\io_context_pool.cpp \ - examples\cpp03\http\server2\main.cpp \ - examples\cpp03\http\server2\mime_types.cpp \ - examples\cpp03\http\server2\reply.cpp \ - examples\cpp03\http\server2\request_handler.cpp \ - examples\cpp03\http\server2\request_parser.cpp \ - examples\cpp03\http\server2\server.cpp - cl -Fe$@ -Foexamples\cpp03\http\server2\ $(CXXFLAGS) $(DEFINES) $** $(LIBS) -link -opt:ref - -examples\cpp03\http\server3\http_server.exe: \ - examples\cpp03\http\server3\connection.cpp \ - examples\cpp03\http\server3\main.cpp \ - examples\cpp03\http\server3\mime_types.cpp \ - examples\cpp03\http\server3\reply.cpp \ - examples\cpp03\http\server3\request_handler.cpp \ - examples\cpp03\http\server3\request_parser.cpp \ - examples\cpp03\http\server3\server.cpp - cl -Fe$@ -Foexamples\cpp03\http\server3\ $(CXXFLAGS) $(DEFINES) $** $(LIBS) -link -opt:ref - -examples\cpp03\http\server4\http_server.exe: \ - examples\cpp03\http\server4\file_handler.cpp \ - examples\cpp03\http\server4\main.cpp \ - examples\cpp03\http\server4\mime_types.cpp \ - examples\cpp03\http\server4\reply.cpp \ - examples\cpp03\http\server4\request_parser.cpp \ - examples\cpp03\http\server4\server.cpp - cl -Fe$@ -Foexamples\cpp03\http\server4\ $(CXXFLAGS) $(DEFINES) $** $(LIBS) -link -opt:ref - -examples\cpp03\services\daytime_client.exe: \ - examples\cpp03\services\daytime_client.cpp \ - examples\cpp03\services\logger_service.cpp - cl -Fe$@ -Foexamples\cpp03\services\ $(CXXFLAGS) $(DEFINES) $** $(LIBS) -link -opt:ref +examples\cpp11\http\server\http_server.exe: \ + examples\cpp11\http\server\connection.cpp \ + examples\cpp11\http\server\connection_manager.cpp \ + examples\cpp11\http\server\main.cpp \ + examples\cpp11\http\server\mime_types.cpp \ + examples\cpp11\http\server\reply.cpp \ + examples\cpp11\http\server\request_handler.cpp \ + examples\cpp11\http\server\request_parser.cpp \ + examples\cpp11\http\server\server.cpp + cl -Fe$@ -Foexamples\cpp11\http\server\ $(CXXFLAGS) $(DEFINES) $** $(LIBS) -link -opt:ref + +examples\cpp11\http\server2\http_server.exe: \ + examples\cpp11\http\server2\connection.cpp \ + examples\cpp11\http\server2\io_context_pool.cpp \ + examples\cpp11\http\server2\main.cpp \ + examples\cpp11\http\server2\mime_types.cpp \ + examples\cpp11\http\server2\reply.cpp \ + examples\cpp11\http\server2\request_handler.cpp \ + examples\cpp11\http\server2\request_parser.cpp \ + examples\cpp11\http\server2\server.cpp + cl -Fe$@ -Foexamples\cpp11\http\server2\ $(CXXFLAGS) $(DEFINES) $** $(LIBS) -link -opt:ref + +examples\cpp11\http\server3\http_server.exe: \ + examples\cpp11\http\server3\connection.cpp \ + examples\cpp11\http\server3\main.cpp \ + examples\cpp11\http\server3\mime_types.cpp \ + examples\cpp11\http\server3\reply.cpp \ + examples\cpp11\http\server3\request_handler.cpp \ + examples\cpp11\http\server3\request_parser.cpp \ + examples\cpp11\http\server3\server.cpp + cl -Fe$@ -Foexamples\cpp11\http\server3\ $(CXXFLAGS) $(DEFINES) $** $(LIBS) -link -opt:ref + +examples\cpp11\http\server4\http_server.exe: \ + examples\cpp11\http\server4\file_handler.cpp \ + examples\cpp11\http\server4\main.cpp \ + examples\cpp11\http\server4\mime_types.cpp \ + examples\cpp11\http\server4\reply.cpp \ + examples\cpp11\http\server4\request_parser.cpp \ + examples\cpp11\http\server4\server.cpp + cl -Fe$@ -Foexamples\cpp11\http\server4\ $(CXXFLAGS) $(DEFINES) $** $(LIBS) -link -opt:ref + +examples\cpp11\services\daytime_client.exe: \ + examples\cpp11\services\daytime_client.cpp \ + examples\cpp11\services\logger_service.cpp + cl -Fe$@ -Foexamples\cpp11\services\ $(CXXFLAGS) $(DEFINES) $** $(LIBS) -link -opt:ref clean: -del /q /s asio.lib diff --git a/asio/src/doc/examples.qbk b/asio/src/doc/examples.qbk index 1f5cfde3e3..dc2b94e27e 100644 --- a/asio/src/doc/examples.qbk +++ b/asio/src/doc/examples.qbk @@ -8,18 +8,10 @@ [section:examples Examples] -* [link asio.examples.cpp03_examples C++03 Examples]: Illustrates the use of -Asio using only C++03 language and library features. Where necessary, the +* [link asio.examples.cpp11_examples C++11 Examples]: Illustrates the use of +Asio using only C++11 language and library features. Where necessary, the examples make use of selected Boost C++ libraries. -* [link asio.examples.cpp11_examples C++11 Examples]: Contains a limited set of -the C++03 Asio examples, updated to use only C++11 library and language -facilities. These examples do not make direct use of Boost C++ libraries. -[/boostify: non-boost docs start here] -To show the changes between C++03 and C++11, these examples include a diff -between the C++03 and C++11 versions. -[/boostify: non-boost docs end here] - * [link asio.examples.cpp14_examples C++14 Examples]: Contains a limited set of the C++03 Asio examples, updated to use only C++14 library and language facilities. These examples do not make direct use of Boost C++ libraries. @@ -31,7 +23,7 @@ illustrating C++17 usage in conjunction with Technical Specifications. using C++20 language features. -[section:cpp03_examples C++03 Examples] +[section:cpp11_examples C++11 Examples] [heading Allocation] @@ -39,7 +31,7 @@ using C++20 language features. This example shows how to customise the allocation of memory associated with asynchronous operations. -* [@../src/examples/cpp03/allocation/server.cpp] +* [@../src/examples/cpp11/allocation/server.cpp] [heading Buffers] @@ -47,7 +39,7 @@ asynchronous operations. This example demonstrates how to create reference counted buffers that can be used with socket read and write operations. -* [@../src/examples/cpp03/buffers/reference_counted.cpp] +* [@../src/examples/cpp11/buffers/reference_counted.cpp] [heading Chat] @@ -55,15 +47,24 @@ used with socket read and write operations. This example implements a chat server and client. The programs use a custom protocol with a fixed length message header and variable length message body. -* [@../src/examples/cpp03/chat/chat_message.hpp] -* [@../src/examples/cpp03/chat/chat_client.cpp] -* [@../src/examples/cpp03/chat/chat_server.cpp] +* [@../src/examples/cpp11/chat/chat_message.hpp] +* [@../src/examples/cpp11/chat/chat_client.cpp] +* [@../src/examples/cpp11/chat/chat_server.cpp] The following POSIX-specific chat client demonstrates how to use the [link asio.reference.posix__stream_descriptor posix::stream_descriptor] class to perform console input and output. -* [@../src/examples/cpp03/chat/posix_chat_client.cpp] +* [@../src/examples/cpp11/chat/posix_chat_client.cpp] + + +[heading Deferred] + +Examples showing how to use the [link asio.reference.deferred `deferred`] +completion token. + +* [@../src/examples/cpp11/deferred/deferred_1.cpp] +* [@../src/examples/cpp11/deferred/deferred_2.cpp] [heading Echo] @@ -71,12 +72,12 @@ perform console input and output. A collection of simple clients and servers, showing the use of both synchronous and asynchronous operations. -* [@../src/examples/cpp03/echo/async_tcp_echo_server.cpp] -* [@../src/examples/cpp03/echo/async_udp_echo_server.cpp] -* [@../src/examples/cpp03/echo/blocking_tcp_echo_client.cpp] -* [@../src/examples/cpp03/echo/blocking_tcp_echo_server.cpp] -* [@../src/examples/cpp03/echo/blocking_udp_echo_client.cpp] -* [@../src/examples/cpp03/echo/blocking_udp_echo_server.cpp] +* [@../src/examples/cpp11/echo/async_tcp_echo_server.cpp] +* [@../src/examples/cpp11/echo/async_udp_echo_server.cpp] +* [@../src/examples/cpp11/echo/blocking_tcp_echo_client.cpp] +* [@../src/examples/cpp11/echo/blocking_tcp_echo_server.cpp] +* [@../src/examples/cpp11/echo/blocking_udp_echo_client.cpp] +* [@../src/examples/cpp11/echo/blocking_udp_echo_server.cpp] [heading Fork] @@ -85,12 +86,32 @@ These POSIX-specific examples show how to use Asio in conjunction with the `fork()` system call. The first example illustrates the steps required to start a daemon process: -* [@../src/examples/cpp03/fork/daemon.cpp] +* [@../src/examples/cpp11/fork/daemon.cpp] The second example demonstrates how it is possible to fork a process from within a completion handler. -* [@../src/examples/cpp03/fork/process_per_connection.cpp] +* [@../src/examples/cpp11/fork/process_per_connection.cpp] + + +[heading Futures] + +This example demonstrates how to use std::future in conjunction with +Asio's asynchronous operations. + +* [@../src/examples/cpp11/futures/daytime_client.cpp] + + +[heading Handler Tracking] + +This example header file shows how to implement custom handler tracking. + +* [@../src/examples/cpp11/handler_tracking/custom_tracking.hpp] + +This example program shows how to include source location information in +the handler tracking output. + +* [@../src/examples/cpp11/handler_tracking/async_tcp_echo_server.cpp] [heading HTTP Client] @@ -99,8 +120,8 @@ Example programs implementing simple HTTP 1.0 clients. These examples show how to use the [link asio.reference.read_until read_until] and [link asio.reference.async_read_until async_read_until] functions. -* [@../src/examples/cpp03/http/client/sync_client.cpp] -* [@../src/examples/cpp03/http/client/async_client.cpp] +* [@../src/examples/cpp11/http/client/sync_client.cpp] +* [@../src/examples/cpp11/http/client/async_client.cpp] [heading HTTP Server] @@ -109,95 +130,95 @@ This example illustrates the use of asio in a simple single-threaded server implementation of HTTP 1.0. It demonstrates how to perform a clean shutdown by cancelling all outstanding asynchronous operations. -* [@../src/examples/cpp03/http/server/connection.cpp] -* [@../src/examples/cpp03/http/server/connection.hpp] -* [@../src/examples/cpp03/http/server/connection_manager.cpp] -* [@../src/examples/cpp03/http/server/connection_manager.hpp] -* [@../src/examples/cpp03/http/server/header.hpp] -* [@../src/examples/cpp03/http/server/main.cpp] -* [@../src/examples/cpp03/http/server/mime_types.cpp] -* [@../src/examples/cpp03/http/server/mime_types.hpp] -* [@../src/examples/cpp03/http/server/reply.cpp] -* [@../src/examples/cpp03/http/server/reply.hpp] -* [@../src/examples/cpp03/http/server/request.hpp] -* [@../src/examples/cpp03/http/server/request_handler.cpp] -* [@../src/examples/cpp03/http/server/request_handler.hpp] -* [@../src/examples/cpp03/http/server/request_parser.cpp] -* [@../src/examples/cpp03/http/server/request_parser.hpp] -* [@../src/examples/cpp03/http/server/server.cpp] -* [@../src/examples/cpp03/http/server/server.hpp] +* [@../src/examples/cpp11/http/server/connection.cpp] +* [@../src/examples/cpp11/http/server/connection.hpp] +* [@../src/examples/cpp11/http/server/connection_manager.cpp] +* [@../src/examples/cpp11/http/server/connection_manager.hpp] +* [@../src/examples/cpp11/http/server/header.hpp] +* [@../src/examples/cpp11/http/server/main.cpp] +* [@../src/examples/cpp11/http/server/mime_types.cpp] +* [@../src/examples/cpp11/http/server/mime_types.hpp] +* [@../src/examples/cpp11/http/server/reply.cpp] +* [@../src/examples/cpp11/http/server/reply.hpp] +* [@../src/examples/cpp11/http/server/request.hpp] +* [@../src/examples/cpp11/http/server/request_handler.cpp] +* [@../src/examples/cpp11/http/server/request_handler.hpp] +* [@../src/examples/cpp11/http/server/request_parser.cpp] +* [@../src/examples/cpp11/http/server/request_parser.hpp] +* [@../src/examples/cpp11/http/server/server.cpp] +* [@../src/examples/cpp11/http/server/server.hpp] [heading HTTP Server 2] An HTTP server using an io_context-per-CPU design. -* [@../src/examples/cpp03/http/server2/connection.cpp] -* [@../src/examples/cpp03/http/server2/connection.hpp] -* [@../src/examples/cpp03/http/server2/header.hpp] -* [@../src/examples/cpp03/http/server2/io_context_pool.cpp] -* [@../src/examples/cpp03/http/server2/io_context_pool.hpp] -* [@../src/examples/cpp03/http/server2/main.cpp] -* [@../src/examples/cpp03/http/server2/mime_types.cpp] -* [@../src/examples/cpp03/http/server2/mime_types.hpp] -* [@../src/examples/cpp03/http/server2/reply.cpp] -* [@../src/examples/cpp03/http/server2/reply.hpp] -* [@../src/examples/cpp03/http/server2/request.hpp] -* [@../src/examples/cpp03/http/server2/request_handler.cpp] -* [@../src/examples/cpp03/http/server2/request_handler.hpp] -* [@../src/examples/cpp03/http/server2/request_parser.cpp] -* [@../src/examples/cpp03/http/server2/request_parser.hpp] -* [@../src/examples/cpp03/http/server2/server.cpp] -* [@../src/examples/cpp03/http/server2/server.hpp] +* [@../src/examples/cpp11/http/server2/connection.cpp] +* [@../src/examples/cpp11/http/server2/connection.hpp] +* [@../src/examples/cpp11/http/server2/header.hpp] +* [@../src/examples/cpp11/http/server2/io_context_pool.cpp] +* [@../src/examples/cpp11/http/server2/io_context_pool.hpp] +* [@../src/examples/cpp11/http/server2/main.cpp] +* [@../src/examples/cpp11/http/server2/mime_types.cpp] +* [@../src/examples/cpp11/http/server2/mime_types.hpp] +* [@../src/examples/cpp11/http/server2/reply.cpp] +* [@../src/examples/cpp11/http/server2/reply.hpp] +* [@../src/examples/cpp11/http/server2/request.hpp] +* [@../src/examples/cpp11/http/server2/request_handler.cpp] +* [@../src/examples/cpp11/http/server2/request_handler.hpp] +* [@../src/examples/cpp11/http/server2/request_parser.cpp] +* [@../src/examples/cpp11/http/server2/request_parser.hpp] +* [@../src/examples/cpp11/http/server2/server.cpp] +* [@../src/examples/cpp11/http/server2/server.hpp] [heading HTTP Server 3] An HTTP server using a single io_context and a thread pool calling `io_context::run()`. -* [@../src/examples/cpp03/http/server3/connection.cpp] -* [@../src/examples/cpp03/http/server3/connection.hpp] -* [@../src/examples/cpp03/http/server3/header.hpp] -* [@../src/examples/cpp03/http/server3/main.cpp] -* [@../src/examples/cpp03/http/server3/mime_types.cpp] -* [@../src/examples/cpp03/http/server3/mime_types.hpp] -* [@../src/examples/cpp03/http/server3/reply.cpp] -* [@../src/examples/cpp03/http/server3/reply.hpp] -* [@../src/examples/cpp03/http/server3/request.hpp] -* [@../src/examples/cpp03/http/server3/request_handler.cpp] -* [@../src/examples/cpp03/http/server3/request_handler.hpp] -* [@../src/examples/cpp03/http/server3/request_parser.cpp] -* [@../src/examples/cpp03/http/server3/request_parser.hpp] -* [@../src/examples/cpp03/http/server3/server.cpp] -* [@../src/examples/cpp03/http/server3/server.hpp] +* [@../src/examples/cpp11/http/server3/connection.cpp] +* [@../src/examples/cpp11/http/server3/connection.hpp] +* [@../src/examples/cpp11/http/server3/header.hpp] +* [@../src/examples/cpp11/http/server3/main.cpp] +* [@../src/examples/cpp11/http/server3/mime_types.cpp] +* [@../src/examples/cpp11/http/server3/mime_types.hpp] +* [@../src/examples/cpp11/http/server3/reply.cpp] +* [@../src/examples/cpp11/http/server3/reply.hpp] +* [@../src/examples/cpp11/http/server3/request.hpp] +* [@../src/examples/cpp11/http/server3/request_handler.cpp] +* [@../src/examples/cpp11/http/server3/request_handler.hpp] +* [@../src/examples/cpp11/http/server3/request_parser.cpp] +* [@../src/examples/cpp11/http/server3/request_parser.hpp] +* [@../src/examples/cpp11/http/server3/server.cpp] +* [@../src/examples/cpp11/http/server3/server.hpp] [heading HTTP Server 4] A single-threaded HTTP server implemented using stackless coroutines. -* [@../src/examples/cpp03/http/server4/file_handler.cpp] -* [@../src/examples/cpp03/http/server4/file_handler.hpp] -* [@../src/examples/cpp03/http/server4/header.hpp] -* [@../src/examples/cpp03/http/server4/main.cpp] -* [@../src/examples/cpp03/http/server4/mime_types.cpp] -* [@../src/examples/cpp03/http/server4/mime_types.hpp] -* [@../src/examples/cpp03/http/server4/reply.cpp] -* [@../src/examples/cpp03/http/server4/reply.hpp] -* [@../src/examples/cpp03/http/server4/request.hpp] -* [@../src/examples/cpp03/http/server4/request_parser.cpp] -* [@../src/examples/cpp03/http/server4/request_parser.hpp] -* [@../src/examples/cpp03/http/server4/server.cpp] -* [@../src/examples/cpp03/http/server4/server.hpp] +* [@../src/examples/cpp11/http/server4/file_handler.cpp] +* [@../src/examples/cpp11/http/server4/file_handler.hpp] +* [@../src/examples/cpp11/http/server4/header.hpp] +* [@../src/examples/cpp11/http/server4/main.cpp] +* [@../src/examples/cpp11/http/server4/mime_types.cpp] +* [@../src/examples/cpp11/http/server4/mime_types.hpp] +* [@../src/examples/cpp11/http/server4/reply.cpp] +* [@../src/examples/cpp11/http/server4/reply.hpp] +* [@../src/examples/cpp11/http/server4/request.hpp] +* [@../src/examples/cpp11/http/server4/request_parser.cpp] +* [@../src/examples/cpp11/http/server4/request_parser.hpp] +* [@../src/examples/cpp11/http/server4/server.cpp] +* [@../src/examples/cpp11/http/server4/server.hpp] [heading ICMP] This example shows how to use raw sockets with ICMP to ping a remote host. -* [@../src/examples/cpp03/icmp/ping.cpp] -* [@../src/examples/cpp03/icmp/ipv4_header.hpp] -* [@../src/examples/cpp03/icmp/icmp_header.hpp] +* [@../src/examples/cpp11/icmp/ping.cpp] +* [@../src/examples/cpp11/icmp/ipv4_header.hpp] +* [@../src/examples/cpp11/icmp/icmp_header.hpp] [heading Invocation] @@ -205,7 +226,7 @@ This example shows how to use raw sockets with ICMP to ping a remote host. This example shows how to customise handler invocation. Completion handlers are added to a priority queue rather than executed immediately. -* [@../src/examples/cpp03/invocation/prioritised_handlers.cpp] +* [@../src/examples/cpp11/invocation/prioritised_handlers.cpp] [heading Iostreams] @@ -213,240 +234,9 @@ added to a priority queue rather than executed immediately. Two examples showing how to use [link asio.reference.ip__tcp.iostream ip::tcp::iostream]. -* [@../src/examples/cpp03/iostreams/daytime_client.cpp] -* [@../src/examples/cpp03/iostreams/daytime_server.cpp] -* [@../src/examples/cpp03/iostreams/http_client.cpp] - - -[heading Multicast] - -An example showing the use of multicast to transmit packets to a group of -subscribers. - -* [@../src/examples/cpp03/multicast/receiver.cpp] -* [@../src/examples/cpp03/multicast/sender.cpp] - - -[heading Serialization] - -This example shows how Boost.Serialization can be used with asio to encode and -decode structures for transmission over a socket. - -* [@../src/examples/cpp03/serialization/client.cpp] -* [@../src/examples/cpp03/serialization/connection.hpp] -* [@../src/examples/cpp03/serialization/server.cpp] -* [@../src/examples/cpp03/serialization/stock.hpp] - - -[heading Services] - -This example demonstrates how to integrate custom functionality (in this case, -for logging) into asio's [link asio.reference.io_context io_context], and -how to use a custom service with [link -asio.reference.basic_stream_socket basic_stream_socket<>]. - -* [@../src/examples/cpp03/services/basic_logger.hpp] -* [@../src/examples/cpp03/services/daytime_client.cpp] -* [@../src/examples/cpp03/services/logger.hpp] -* [@../src/examples/cpp03/services/logger_service.cpp] -* [@../src/examples/cpp03/services/logger_service.hpp] -* [@../src/examples/cpp03/services/stream_socket_service.hpp] - - -[heading SOCKS 4] - -Example client program implementing the SOCKS 4 protocol for communication via -a proxy. - -* [@../src/examples/cpp03/socks4/sync_client.cpp] -* [@../src/examples/cpp03/socks4/socks4.hpp] - - -[heading SSL] - -Example client and server programs showing the use of the [link -asio.reference.ssl__stream ssl::stream<>] template with asynchronous operations. - -* [@../src/examples/cpp03/ssl/client.cpp] -* [@../src/examples/cpp03/ssl/server.cpp] - - -[heading Timeouts] - -A collection of examples showing how to cancel long running asynchronous -operations after a period of time. - -* [@../src/examples/cpp03/timeouts/async_tcp_client.cpp] -* [@../src/examples/cpp03/timeouts/blocking_tcp_client.cpp] -* [@../src/examples/cpp03/timeouts/blocking_token_tcp_client.cpp] -* [@../src/examples/cpp03/timeouts/blocking_udp_client.cpp] -* [@../src/examples/cpp03/timeouts/server.cpp] - - -[heading Timers] - -Example showing how to customise basic_waitable_timer using a different clock type. - -* [@../src/examples/cpp03/timers/time_t_timer.cpp] - - -[heading Porthopper] - -Example illustrating mixed synchronous and asynchronous operations, and how to -use Boost.Lambda with Asio. - -* [@../src/examples/cpp03/porthopper/protocol.hpp] -* [@../src/examples/cpp03/porthopper/client.cpp] -* [@../src/examples/cpp03/porthopper/server.cpp] - - -[heading Nonblocking] - -Example demonstrating reactor-style operations for integrating a third-party -library that wants to perform the I/O operations itself. - -* [@../src/examples/cpp03/nonblocking/third_party_lib.cpp] - - -[heading Spawn] - -Example of using the asio::spawn() function, a wrapper around the -[@http://www.boost.org/doc/libs/release/libs/coroutine/index.html Boost.Coroutine] -library, to implement a chain of asynchronous operations using stackful -coroutines. - -* [@../src/examples/cpp03/spawn/echo_server.cpp] - - -[heading UNIX Domain Sockets] - -Examples showing how to use UNIX domain (local) sockets. - -* [@../src/examples/cpp03/local/connect_pair.cpp] -* [@../src/examples/cpp03/local/iostream_client.cpp] -* [@../src/examples/cpp03/local/stream_server.cpp] -* [@../src/examples/cpp03/local/stream_client.cpp] - - -[heading Windows] - -An example showing how to use the Windows-specific function `TransmitFile` -with Asio. - -* [@../src/examples/cpp03/windows/transmit_file.cpp] - - -[endsect] - - -[section:cpp11_examples C++11 Examples] - - -[heading Allocation] - -This example shows how to customise the allocation of memory associated with -asynchronous operations. - -* [@../src/examples/cpp11/allocation/server.cpp] ([@examples/diffs/allocation/server.cpp.html diff to C++03]) - - -[heading Buffers] - -This example demonstrates how to create reference counted buffers that can be -used with socket read and write operations. - -* [@../src/examples/cpp11/buffers/reference_counted.cpp] ([@examples/diffs/buffers/reference_counted.cpp.html diff to C++03]) - - -[heading Chat] - -This example implements a chat server and client. The programs use a custom -protocol with a fixed length message header and variable length message body. - -* [@../src/examples/cpp11/chat/chat_message.hpp] ([@examples/diffs/chat/chat_message.hpp.html diff to C++03]) -* [@../src/examples/cpp11/chat/chat_client.cpp] ([@examples/diffs/chat/chat_client.cpp.html diff to C++03]) -* [@../src/examples/cpp11/chat/chat_server.cpp] ([@examples/diffs/chat/chat_server.cpp.html diff to C++03]) - - -[heading Echo] - -A collection of simple clients and servers, showing the use of both synchronous -and asynchronous operations. - -* [@../src/examples/cpp11/echo/async_tcp_echo_server.cpp] ([@examples/diffs/echo/async_tcp_echo_server.cpp.html diff to C++03]) -* [@../src/examples/cpp11/echo/async_udp_echo_server.cpp] ([@examples/diffs/echo/async_udp_echo_server.cpp.html diff to C++03]) -* [@../src/examples/cpp11/echo/blocking_tcp_echo_client.cpp] ([@examples/diffs/echo/blocking_tcp_echo_client.cpp.html diff to C++03]) -* [@../src/examples/cpp11/echo/blocking_tcp_echo_server.cpp] ([@examples/diffs/echo/blocking_tcp_echo_server.cpp.html diff to C++03]) -* [@../src/examples/cpp11/echo/blocking_udp_echo_client.cpp] ([@examples/diffs/echo/blocking_udp_echo_client.cpp.html diff to C++03]) -* [@../src/examples/cpp11/echo/blocking_udp_echo_server.cpp] ([@examples/diffs/echo/blocking_udp_echo_server.cpp.html diff to C++03]) - - -[heading Deferred] - -Examples showing how to use the [link asio.reference.deferred `deferred`] -completion token. - -* [@../src/examples/cpp11/deferred/deferred_1.cpp] -* [@../src/examples/cpp11/deferred/deferred_2.cpp] - - -[heading Fork] - -These POSIX-specific examples show how to use Asio in conjunction with the -`fork()` system call. The first example illustrates the steps required to start -a daemon process: - -* [@../src/examples/cpp11/fork/daemon.cpp] ([@examples/diffs/fork/daemon.cpp.html diff to C++03]) - -The second example demonstrates how it is possible to fork a process from -within a completion handler. - -* [@../src/examples/cpp11/fork/process_per_connection.cpp] ([@examples/diffs/fork/process_per_connection.cpp.html diff to C++03]) - - -[heading Futures] - -This example demonstrates how to use std::future in conjunction with -Asio's asynchronous operations. - -* [@../src/examples/cpp11/futures/daytime_client.cpp] - - -[heading Handler Tracking] - -This example header file shows how to implement custom handler tracking. - -* [@../src/examples/cpp11/handler_tracking/custom_tracking.hpp] - -This example program shows how to include source location information in -the handler tracking output. - -* [@../src/examples/cpp11/handler_tracking/async_tcp_echo_server.cpp] - - -[heading HTTP Server] - -This example illustrates the use of asio in a simple single-threaded server -implementation of HTTP 1.0. It demonstrates how to perform a clean shutdown by -cancelling all outstanding asynchronous operations. - -* [@../src/examples/cpp11/http/server/connection.cpp] ([@examples/diffs/http/server/connection.cpp.html diff to C++03]) -* [@../src/examples/cpp11/http/server/connection.hpp] ([@examples/diffs/http/server/connection.hpp.html diff to C++03]) -* [@../src/examples/cpp11/http/server/connection_manager.cpp] ([@examples/diffs/http/server/connection_manager.cpp.html diff to C++03]) -* [@../src/examples/cpp11/http/server/connection_manager.hpp] ([@examples/diffs/http/server/connection_manager.hpp.html diff to C++03]) -* [@../src/examples/cpp11/http/server/header.hpp] ([@examples/diffs/http/server/header.hpp.html diff to C++03]) -* [@../src/examples/cpp11/http/server/main.cpp] ([@examples/diffs/http/server/main.cpp.html diff to C++03]) -* [@../src/examples/cpp11/http/server/mime_types.cpp] ([@examples/diffs/http/server/mime_types.cpp.html diff to C++03]) -* [@../src/examples/cpp11/http/server/mime_types.hpp] ([@examples/diffs/http/server/mime_types.hpp.html diff to C++03]) -* [@../src/examples/cpp11/http/server/reply.cpp] ([@examples/diffs/http/server/reply.cpp.html diff to C++03]) -* [@../src/examples/cpp11/http/server/reply.hpp] ([@examples/diffs/http/server/reply.hpp.html diff to C++03]) -* [@../src/examples/cpp11/http/server/request.hpp] ([@examples/diffs/http/server/request.hpp.html diff to C++03]) -* [@../src/examples/cpp11/http/server/request_handler.cpp] ([@examples/diffs/http/server/request_handler.cpp.html diff to C++03]) -* [@../src/examples/cpp11/http/server/request_handler.hpp] ([@examples/diffs/http/server/request_handler.hpp.html diff to C++03]) -* [@../src/examples/cpp11/http/server/request_parser.cpp] ([@examples/diffs/http/server/request_parser.cpp.html diff to C++03]) -* [@../src/examples/cpp11/http/server/request_parser.hpp] ([@examples/diffs/http/server/request_parser.hpp.html diff to C++03]) -* [@../src/examples/cpp11/http/server/server.cpp] ([@examples/diffs/http/server/server.cpp.html diff to C++03]) -* [@../src/examples/cpp11/http/server/server.hpp] ([@examples/diffs/http/server/server.hpp.html diff to C++03]) +* [@../src/examples/cpp11/iostreams/daytime_client.cpp] +* [@../src/examples/cpp11/iostreams/daytime_server.cpp] +* [@../src/examples/cpp11/iostreams/http_client.cpp] [heading Multicast] @@ -454,8 +244,8 @@ cancelling all outstanding asynchronous operations. An example showing the use of multicast to transmit packets to a group of subscribers. -* [@../src/examples/cpp11/multicast/receiver.cpp] ([@examples/diffs/multicast/receiver.cpp.html diff to C++03]) -* [@../src/examples/cpp11/multicast/sender.cpp] ([@examples/diffs/multicast/sender.cpp.html diff to C++03]) +* [@../src/examples/cpp11/multicast/receiver.cpp] +* [@../src/examples/cpp11/multicast/sender.cpp] [heading Nonblocking] @@ -463,7 +253,7 @@ subscribers. Example demonstrating reactor-style operations for integrating a third-party library that wants to perform the I/O operations itself. -* [@../src/examples/cpp11/nonblocking/third_party_lib.cpp] ([@examples/diffs/nonblocking/third_party_lib.cpp.html diff to C++03]) +* [@../src/examples/cpp11/nonblocking/third_party_lib.cpp] [heading Operations] @@ -493,23 +283,58 @@ asio.reference.experimental__make_parallel_group * [@../src/examples/cpp11/parallel_group/ranged_wait_for_all.cpp] +[heading Porthopper] + +Example illustrating mixed synchronous and asynchronous operations. + +* [@../src/examples/cpp11/porthopper/protocol.hpp] +* [@../src/examples/cpp11/porthopper/client.cpp] +* [@../src/examples/cpp11/porthopper/server.cpp] + + +[heading Serialization] + +This example shows how Boost.Serialization can be used with asio to encode and +decode structures for transmission over a socket. + +* [@../src/examples/cpp11/serialization/client.cpp] +* [@../src/examples/cpp11/serialization/connection.hpp] +* [@../src/examples/cpp11/serialization/server.cpp] +* [@../src/examples/cpp11/serialization/stock.hpp] + + +[heading Services] + +This example demonstrates how to integrate custom functionality (in this case, +for logging) into asio's [link asio.reference.io_context io_context], and +how to use a custom service with [link +asio.reference.basic_stream_socket basic_stream_socket<>]. + +* [@../src/examples/cpp11/services/basic_logger.hpp] +* [@../src/examples/cpp11/services/daytime_client.cpp] +* [@../src/examples/cpp11/services/logger.hpp] +* [@../src/examples/cpp11/services/logger_service.cpp] +* [@../src/examples/cpp11/services/logger_service.hpp] +* [@../src/examples/cpp11/services/stream_socket_service.hpp] + + [heading SOCKS 4] Example client program implementing the SOCKS 4 protocol for communication via a proxy. -* [@../src/examples/cpp11/socks4/sync_client.cpp] ([@examples/diffs/socks4/sync_client.cpp.html diff to C++03]) -* [@../src/examples/cpp11/socks4/socks4.hpp] ([@examples/diffs/socks4/socks4.hpp.html diff to C++03]) +* [@../src/examples/cpp11/socks4/sync_client.cpp] +* [@../src/examples/cpp11/socks4/socks4.hpp] [heading Spawn] Example of using the asio::spawn() function, a wrapper around the -[@http://www.boost.org/doc/libs/release/libs/coroutine/index.html Boost.Coroutine] +[@http://www.boost.org/doc/libs/release/libs/context/index.html Boost.Context] library, to implement a chain of asynchronous operations using stackful coroutines. -* [@../src/examples/cpp11/spawn/echo_server.cpp] ([@examples/diffs/spawn/echo_server.cpp.html diff to C++03]) +* [@../src/examples/cpp11/spawn/echo_server.cpp] [heading SSL] @@ -517,8 +342,8 @@ coroutines. Example client and server programs showing the use of the [link asio.reference.ssl__stream ssl::stream<>] template with asynchronous operations. -* [@../src/examples/cpp11/ssl/client.cpp] ([@examples/diffs/ssl/client.cpp.html diff to C++03]) -* [@../src/examples/cpp11/ssl/server.cpp] ([@examples/diffs/ssl/server.cpp.html diff to C++03]) +* [@../src/examples/cpp11/ssl/client.cpp] +* [@../src/examples/cpp11/ssl/server.cpp] [heading Timeouts] @@ -526,18 +351,18 @@ asio.reference.ssl__stream ssl::stream<>] template with asynchronous operations. A collection of examples showing how to cancel long running asynchronous operations after a period of time. -* [@../src/examples/cpp11/timeouts/async_tcp_client.cpp] ([@examples/diffs/timeouts/async_tcp_client.cpp.html diff to C++03]) -* [@../src/examples/cpp11/timeouts/blocking_tcp_client.cpp] ([@examples/diffs/timeouts/blocking_tcp_client.cpp.html diff to C++03]) -* [@../src/examples/cpp11/timeouts/blocking_token_tcp_client.cpp] ([@examples/diffs/timeouts/blocking_token_tcp_client.cpp.html diff to C++03]) -* [@../src/examples/cpp11/timeouts/blocking_udp_client.cpp] ([@examples/diffs/timeouts/blocking_udp_client.cpp.html diff to C++03]) -* [@../src/examples/cpp11/timeouts/server.cpp] ([@examples/diffs/timeouts/server.cpp.html diff to C++03]) +* [@../src/examples/cpp11/timeouts/async_tcp_client.cpp] +* [@../src/examples/cpp11/timeouts/blocking_tcp_client.cpp] +* [@../src/examples/cpp11/timeouts/blocking_token_tcp_client.cpp] +* [@../src/examples/cpp11/timeouts/blocking_udp_client.cpp] +* [@../src/examples/cpp11/timeouts/server.cpp] [heading Timers] Example showing how to customise basic_waitable_timer using a different clock type. -* [@../src/examples/cpp11/timers/time_t_timer.cpp] ([@examples/diffs/timers/time_t_timer.cpp.html diff to C++03]) +* [@../src/examples/cpp11/timers/time_t_timer.cpp] [heading Type Erasure] @@ -558,14 +383,22 @@ operations. Examples showing how to use UNIX domain (local) sockets. -* [@../src/examples/cpp11/local/connect_pair.cpp] ([@examples/diffs/local/connect_pair.cpp.html diff to C++03]) -* [@../src/examples/cpp11/local/iostream_client.cpp] ([@examples/diffs/local/iostream_client.cpp.html diff to C++03]) -* [@../src/examples/cpp11/local/stream_server.cpp] ([@examples/diffs/local/stream_server.cpp.html diff to C++03]) -* [@../src/examples/cpp11/local/stream_client.cpp] ([@examples/diffs/local/stream_client.cpp.html diff to C++03]) +* [@../src/examples/cpp11/local/connect_pair.cpp] +* [@../src/examples/cpp11/local/iostream_client.cpp] +* [@../src/examples/cpp11/local/stream_server.cpp] +* [@../src/examples/cpp11/local/stream_client.cpp] * [@../src/examples/cpp11/local/fd_passing_stream_server.cpp] * [@../src/examples/cpp11/local/fd_passing_stream_client.cpp] +[heading Windows] + +An example showing how to use the Windows-specific function `TransmitFile` +with Asio. + +* [@../src/examples/cpp11/windows/transmit_file.cpp] + + [endsect] diff --git a/asio/src/doc/overview/allocation.qbk b/asio/src/doc/overview/allocation.qbk index 47cf45e5db..4db273075b 100644 --- a/asio/src/doc/overview/allocation.qbk +++ b/asio/src/doc/overview/allocation.qbk @@ -89,7 +89,6 @@ responsible for providing the necessary thread safety guarantees.) [link asio.reference.associated_allocator associated_allocator], [link asio.reference.get_associated_allocator get_associated_allocator], -[link asio.examples.cpp03_examples.allocation custom memory allocation example (C++03)], [link asio.examples.cpp11_examples.allocation custom memory allocation example (C++11)]. [endsect] diff --git a/asio/src/doc/overview/buffers.qbk b/asio/src/doc/overview/buffers.qbk index c4c6db6360..e52789a56c 100644 --- a/asio/src/doc/overview/buffers.qbk +++ b/asio/src/doc/overview/buffers.qbk @@ -179,7 +179,6 @@ It can also be explicitly disabled by defining `ASIO_DISABLE_BUFFER_DEBUGGING`. [link asio.reference.streambuf streambuf], [link asio.reference.ConstBufferSequence ConstBufferSequence], [link asio.reference.MutableBufferSequence MutableBufferSequence], -[link asio.examples.cpp03_examples.buffers buffers example (C++03)], [link asio.examples.cpp11_examples.buffers buffers example (c++11)]. [endsect] diff --git a/asio/src/doc/overview/coroutine.qbk b/asio/src/doc/overview/coroutine.qbk index ec3b6e7f3c..bacda75f33 100644 --- a/asio/src/doc/overview/coroutine.qbk +++ b/asio/src/doc/overview/coroutine.qbk @@ -45,7 +45,7 @@ documentation provides a complete description of these pseudo-keywords. [heading See Also] [link asio.reference.coroutine coroutine], -[link asio.examples.cpp03_examples.http_server_4 HTTP Server 4 example], +[link asio.examples.cpp11_examples.http_server_4 HTTP Server 4 example], [link asio.overview.composition.spawn Stackful Coroutines]. [endsect] diff --git a/asio/src/doc/overview/iostreams.qbk b/asio/src/doc/overview/iostreams.qbk index 34ff661035..4074c59080 100644 --- a/asio/src/doc/overview/iostreams.qbk +++ b/asio/src/doc/overview/iostreams.qbk @@ -62,7 +62,7 @@ retrieve the error code from the most recent system call: [link asio.reference.ip__tcp.iostream ip::tcp::iostream], [link asio.reference.basic_socket_iostream basic_socket_iostream], -[link asio.examples.cpp03_examples.iostreams iostreams examples]. +[link asio.examples.cpp11_examples.iostreams iostreams examples]. [heading Notes] diff --git a/asio/src/doc/overview/line_based.qbk b/asio/src/doc/overview/line_based.qbk index ecd72dcba3..9eb465a411 100644 --- a/asio/src/doc/overview/line_based.qbk +++ b/asio/src/doc/overview/line_based.qbk @@ -113,6 +113,6 @@ other types the trait must be explicitly specialised, as shown above. [link asio.reference.is_match_condition is_match_condition], [link asio.reference.read_until read_until()], [link asio.reference.streambuf streambuf], -[link asio.examples.cpp03_examples.http_client HTTP client example]. +[link asio.examples.cpp11_examples.http_client HTTP client example]. [endsect] diff --git a/asio/src/doc/overview/posix.qbk b/asio/src/doc/overview/posix.qbk index 8cf9664a96..765b6aa59e 100644 --- a/asio/src/doc/overview/posix.qbk +++ b/asio/src/doc/overview/posix.qbk @@ -61,7 +61,7 @@ asio.reference.basic_socket.native_handle native_handle()] member function. [link asio.reference.local__stream_protocol.endpoint local::stream_protocol::endpoint], [link asio.reference.local__stream_protocol.iostream local::stream_protocol::iostream], [link asio.reference.local__stream_protocol.socket local::stream_protocol::socket], -[link asio.examples.cpp03_examples.unix_domain_sockets UNIX domain sockets examples]. +[link asio.examples.cpp11_examples.unix_domain_sockets UNIX domain sockets examples]. [heading Notes] @@ -101,7 +101,6 @@ asio.reference.async_read_until async_read_until()] free functions. [heading See Also] [link asio.reference.posix__stream_descriptor posix::stream_descriptor], -[link asio.examples.cpp03_examples.chat Chat example (C++03)], [link asio.examples.cpp11_examples.chat Chat example (C++11)]. [heading Notes] @@ -145,7 +144,7 @@ as required. [link asio.reference.io_context.notify_fork io_context::notify_fork()], [link asio.reference.io_context.fork_event io_context::fork_event], [link asio.reference.execution_context__service.notify_fork io_context::service::notify_fork()], -[link asio.examples.cpp03_examples.fork Fork examples]. +[link asio.examples.cpp11_examples.fork Fork examples]. [endsect] diff --git a/asio/src/doc/overview/protocols.qbk b/asio/src/doc/overview/protocols.qbk index 51aa75755a..deb92e14af 100644 --- a/asio/src/doc/overview/protocols.qbk +++ b/asio/src/doc/overview/protocols.qbk @@ -144,6 +144,6 @@ functions. [link asio.reference.ip__udp ip::udp], [link asio.reference.ip__icmp ip::icmp], [link asio.tutorial.tutdaytime1 daytime protocol tutorials], -[link asio.examples.cpp03_examples.icmp ICMP ping example]. +[link asio.examples.cpp11_examples.icmp ICMP ping example]. [endsect] diff --git a/asio/src/doc/overview/reactor.qbk b/asio/src/doc/overview/reactor.qbk index 16eec38b50..4e67a5d765 100644 --- a/asio/src/doc/overview/reactor.qbk +++ b/asio/src/doc/overview/reactor.qbk @@ -39,6 +39,6 @@ stream-oriented descriptor classes. [link asio.reference.basic_socket.async_wait basic_socket::async_wait()], [link asio.reference.basic_socket.non_blocking basic_socket::non_blocking()], [link asio.reference.basic_socket.native_non_blocking basic_socket::native_non_blocking()], -[link asio.examples.cpp03_examples.nonblocking nonblocking example]. +[link asio.examples.cpp11_examples.nonblocking nonblocking example]. [endsect] diff --git a/asio/src/doc/overview/signals.qbk b/asio/src/doc/overview/signals.qbk index 49d2bd4682..8f3c6cc659 100644 --- a/asio/src/doc/overview/signals.qbk +++ b/asio/src/doc/overview/signals.qbk @@ -38,7 +38,6 @@ library maps console events like Ctrl+C to the equivalent signal. [heading See Also] [link asio.reference.signal_set signal_set], -[link asio.examples.cpp03_examples.http_server HTTP server example (C++03)], [link asio.examples.cpp11_examples.http_server HTTP server example (C++11)]. [endsect] diff --git a/asio/src/doc/overview/spawn.qbk b/asio/src/doc/overview/spawn.qbk index 9d0cc63f42..fbf0f9d97e 100644 --- a/asio/src/doc/overview/spawn.qbk +++ b/asio/src/doc/overview/spawn.qbk @@ -92,7 +92,6 @@ function object signature is actually: [link asio.reference.spawn spawn], [link asio.reference.yield_context yield_context], [link asio.reference.basic_yield_context basic_yield_context], -[link asio.examples.cpp03_examples.spawn Spawn example (C++03)], [link asio.examples.cpp11_examples.spawn Spawn example (C++11)], [link asio.overview.composition.coroutine Stackless Coroutines]. diff --git a/asio/src/doc/overview/ssl.qbk b/asio/src/doc/overview/ssl.qbk index 80651c6781..1b5f3c920a 100644 --- a/asio/src/doc/overview/ssl.qbk +++ b/asio/src/doc/overview/ssl.qbk @@ -110,7 +110,6 @@ threaded programs. [link asio.reference.ssl__context ssl::context], [link asio.reference.ssl__host_name_verification ssl::host_name_verification], [link asio.reference.ssl__stream ssl::stream], -[link asio.examples.cpp03_examples.ssl SSL example (C++03)], [link asio.examples.cpp11_examples.ssl SSL example (C++11)]. [heading Notes] diff --git a/asio/src/doc/overview/strands.qbk b/asio/src/doc/overview/strands.qbk index 8dfa53dd23..81e70f7d07 100644 --- a/asio/src/doc/overview/strands.qbk +++ b/asio/src/doc/overview/strands.qbk @@ -109,6 +109,6 @@ completion handler we would simply write: [link asio.reference.strand strand], [link asio.reference.io_context__strand io_context::strand], [link asio.tutorial.tuttimer5 tutorial Timer.5], -[link asio.examples.cpp03_examples.http_server_3 HTTP server 3 example]. +[link asio.examples.cpp11_examples.http_server_3 HTTP server 3 example]. [endsect] diff --git a/asio/src/doc/tutorial.dox b/asio/src/doc/tutorial.dox index c362f951c1..0295f0e5ee 100644 --- a/asio/src/doc/tutorial.dox +++ b/asio/src/doc/tutorial.dox @@ -114,9 +114,9 @@ WARN_LOGFILE = #--------------------------------------------------------------------------- # Configuration options related to the input files #--------------------------------------------------------------------------- -INPUT = ./../examples/cpp03/tutorial/index_dox.txt \ - ./../examples/cpp03/tutorial/timer_dox.txt \ - ./../examples/cpp03/tutorial/daytime_dox.txt \ +INPUT = ./../examples/cpp11/tutorial/index_dox.txt \ + ./../examples/cpp11/tutorial/timer_dox.txt \ + ./../examples/cpp11/tutorial/daytime_dox.txt \ ./boost_bind_dox.txt INPUT_ENCODING = UTF-8 INPUT_FILE_ENCODING = diff --git a/asio/src/examples/cpp03/Makefile.am b/asio/src/examples/cpp03/Makefile.am deleted file mode 100644 index 0fab176c6f..0000000000 --- a/asio/src/examples/cpp03/Makefile.am +++ /dev/null @@ -1,251 +0,0 @@ -AUTOMAKE_OPTIONS = subdir-objects - -if SEPARATE_COMPILATION -noinst_LIBRARIES = libasio.a -libasio_a_SOURCES = ../../asio.cpp -if HAVE_OPENSSL -libasio_a_SOURCES += ../../asio_ssl.cpp -endif -LDADD = libasio.a -endif - -noinst_PROGRAMS = \ - allocation/server \ - buffers/reference_counted \ - chat/chat_client \ - chat/chat_server \ - echo/async_tcp_echo_server \ - echo/async_udp_echo_server \ - echo/blocking_tcp_echo_client \ - echo/blocking_tcp_echo_server \ - echo/blocking_udp_echo_client \ - echo/blocking_udp_echo_server \ - http/client/async_client \ - http/client/sync_client \ - http/server/http_server \ - http/server2/http_server \ - http/server3/http_server \ - http/server4/http_server \ - icmp/ping \ - invocation/prioritised_handlers \ - iostreams/daytime_client \ - iostreams/daytime_server \ - iostreams/http_client \ - multicast/receiver \ - multicast/sender \ - nonblocking/third_party_lib \ - porthopper/client \ - porthopper/server \ - services/daytime_client \ - socks4/sync_client \ - timeouts/async_tcp_client \ - timeouts/blocking_tcp_client \ - timeouts/blocking_token_tcp_client \ - timeouts/blocking_udp_client \ - timeouts/server \ - timers/time_t_timer \ - tutorial/timer1/timer \ - tutorial/timer2/timer \ - tutorial/timer3/timer \ - tutorial/timer4/timer \ - tutorial/timer5/timer \ - tutorial/daytime1/client \ - tutorial/daytime2/server \ - tutorial/daytime3/server \ - tutorial/daytime4/client \ - tutorial/daytime5/server \ - tutorial/daytime6/server \ - tutorial/daytime7/server - -if !WINDOWS_TARGET -noinst_PROGRAMS += \ - chat/posix_chat_client \ - fork/daemon \ - fork/process_per_connection \ - local/connect_pair \ - local/iostream_client \ - local/stream_server \ - local/stream_client -endif - -if WINDOWS_TARGET -noinst_PROGRAMS += \ - windows/transmit_file -endif - -if HAVE_OPENSSL -noinst_PROGRAMS += \ - ssl/client \ - ssl/server -endif - -if HAVE_BOOST_COROUTINE -noinst_PROGRAMS += \ - spawn/echo_server \ - spawn/parallel_grep -endif - -noinst_HEADERS = \ - chat/chat_message.hpp \ - services/basic_logger.hpp \ - services/logger.hpp \ - services/logger_service.hpp - -AM_CXXFLAGS = -I$(srcdir)/../../../include - -allocation_server_SOURCES = allocation/server.cpp -buffers_reference_counted_SOURCES = buffers/reference_counted.cpp -chat_chat_client_SOURCES = chat/chat_client.cpp -chat_chat_server_SOURCES = chat/chat_server.cpp -echo_async_tcp_echo_server_SOURCES = echo/async_tcp_echo_server.cpp -echo_async_udp_echo_server_SOURCES = echo/async_udp_echo_server.cpp -echo_blocking_tcp_echo_client_SOURCES = echo/blocking_tcp_echo_client.cpp -echo_blocking_tcp_echo_server_SOURCES = echo/blocking_tcp_echo_server.cpp -echo_blocking_udp_echo_client_SOURCES = echo/blocking_udp_echo_client.cpp -echo_blocking_udp_echo_server_SOURCES = echo/blocking_udp_echo_server.cpp -http_client_async_client_SOURCES = http/client/async_client.cpp -http_client_sync_client_SOURCES = http/client/sync_client.cpp -http_server_http_server_SOURCES = \ - http/server/connection.cpp \ - http/server/connection_manager.cpp \ - http/server/main.cpp \ - http/server/mime_types.cpp \ - http/server/reply.cpp \ - http/server/request_handler.cpp \ - http/server/request_parser.cpp \ - http/server/server.cpp -http_server2_http_server_SOURCES = \ - http/server2/connection.cpp \ - http/server2/io_context_pool.cpp \ - http/server2/main.cpp \ - http/server2/mime_types.cpp \ - http/server2/reply.cpp \ - http/server2/request_handler.cpp \ - http/server2/request_parser.cpp \ - http/server2/server.cpp -http_server3_http_server_SOURCES = \ - http/server3/connection.cpp \ - http/server3/main.cpp \ - http/server3/mime_types.cpp \ - http/server3/reply.cpp \ - http/server3/request_handler.cpp \ - http/server3/request_parser.cpp \ - http/server3/server.cpp -http_server4_http_server_SOURCES = \ - http/server4/file_handler.cpp \ - http/server4/main.cpp \ - http/server4/mime_types.cpp \ - http/server4/reply.cpp \ - http/server4/request_parser.cpp \ - http/server4/server.cpp -icmp_ping_SOURCES = icmp/ping.cpp -invocation_prioritised_handlers_SOURCES = invocation/prioritised_handlers.cpp -iostreams_daytime_client_SOURCES = iostreams/daytime_client.cpp -iostreams_daytime_server_SOURCES = iostreams/daytime_server.cpp -iostreams_http_client_SOURCES = iostreams/http_client.cpp -multicast_receiver_SOURCES = multicast/receiver.cpp -multicast_sender_SOURCES = multicast/sender.cpp -nonblocking_third_party_lib_SOURCES = nonblocking/third_party_lib.cpp -porthopper_client_SOURCES = porthopper/client.cpp -porthopper_server_SOURCES = porthopper/server.cpp -services_daytime_client_SOURCES = \ - services/daytime_client.cpp \ - services/logger_service.cpp -socks4_sync_client_SOURCES = socks4/sync_client.cpp -timeouts_async_tcp_client_SOURCES = timeouts/async_tcp_client.cpp -timeouts_blocking_tcp_client_SOURCES = timeouts/blocking_tcp_client.cpp -timeouts_blocking_token_tcp_client_SOURCES = timeouts/blocking_token_tcp_client.cpp -timeouts_blocking_udp_client_SOURCES = timeouts/blocking_udp_client.cpp -timeouts_server_SOURCES = timeouts/server.cpp -timers_time_t_timer_SOURCES = timers/time_t_timer.cpp -tutorial_timer1_timer_SOURCES = tutorial/timer1/timer.cpp -tutorial_timer2_timer_SOURCES = tutorial/timer2/timer.cpp -tutorial_timer3_timer_SOURCES = tutorial/timer3/timer.cpp -tutorial_timer4_timer_SOURCES = tutorial/timer4/timer.cpp -tutorial_timer5_timer_SOURCES = tutorial/timer5/timer.cpp -tutorial_daytime1_client_SOURCES = tutorial/daytime1/client.cpp -tutorial_daytime2_server_SOURCES = tutorial/daytime2/server.cpp -tutorial_daytime3_server_SOURCES = tutorial/daytime3/server.cpp -tutorial_daytime4_client_SOURCES = tutorial/daytime4/client.cpp -tutorial_daytime5_server_SOURCES = tutorial/daytime5/server.cpp -tutorial_daytime6_server_SOURCES = tutorial/daytime6/server.cpp -tutorial_daytime7_server_SOURCES = tutorial/daytime7/server.cpp - -if !WINDOWS_TARGET -chat_posix_chat_client_SOURCES = chat/posix_chat_client.cpp -fork_daemon_SOURCES = fork/daemon.cpp -fork_process_per_connection_SOURCES = fork/process_per_connection.cpp -local_connect_pair_SOURCES = local/connect_pair.cpp -local_iostream_client_SOURCES = local/iostream_client.cpp -local_stream_server_SOURCES = local/stream_server.cpp -local_stream_client_SOURCES = local/stream_client.cpp -endif - -if WINDOWS_TARGET -windows_transmit_file_SOURCES = windows/transmit_file.cpp -endif - -if HAVE_OPENSSL -ssl_client_SOURCES = ssl/client.cpp -ssl_server_SOURCES = ssl/server.cpp -endif - -if HAVE_BOOST_COROUTINE -spawn_echo_server_SOURCES = spawn/echo_server.cpp -spawn_echo_server_LDADD = $(LDADD) -lboost_coroutine -lboost_context -lboost_thread -lboost_chrono -lboost_system -spawn_parallel_grep_SOURCES = spawn/parallel_grep.cpp -spawn_parallel_grep_LDADD = $(LDADD) -lboost_coroutine -lboost_context -lboost_thread -lboost_chrono -lboost_system -endif - -EXTRA_DIST = \ - http/server/connection.hpp \ - http/server/connection_manager.hpp \ - http/server/header.hpp \ - http/server/mime_types.hpp \ - http/server/reply.hpp \ - http/server/request.hpp \ - http/server/request_handler.hpp \ - http/server/request_parser.hpp \ - http/server/server.hpp \ - http/server2/connection.hpp \ - http/server2/io_context_pool.hpp \ - http/server2/header.hpp \ - http/server2/mime_types.hpp \ - http/server2/reply.hpp \ - http/server2/request.hpp \ - http/server2/request_handler.hpp \ - http/server2/request_parser.hpp \ - http/server2/server.hpp \ - http/server3/connection.hpp \ - http/server3/header.hpp \ - http/server3/mime_types.hpp \ - http/server3/reply.hpp \ - http/server3/request.hpp \ - http/server3/request_handler.hpp \ - http/server3/request_parser.hpp \ - http/server3/server.hpp \ - http/server4/file_handler.hpp \ - http/server4/header.hpp \ - http/server4/mime_types.hpp \ - http/server4/reply.hpp \ - http/server4/request.hpp \ - http/server4/request_parser.hpp \ - http/server4/server.hpp \ - icmp/icmp_header.hpp \ - icmp/ipv4_header.hpp \ - porthopper/protocol.hpp \ - serialization/client.cpp \ - serialization/server.cpp \ - serialization/connection.hpp \ - serialization/stock.hpp \ - services/basic_logger.hpp \ - services/logger.hpp \ - services/logger_service.hpp \ - socks4/socks4.hpp \ - ssl/README \ - ssl/ca.pem \ - ssl/server.pem \ - ssl/dh4096.pem - -MAINTAINERCLEANFILES = \ - $(srcdir)/Makefile.in diff --git a/asio/src/examples/cpp03/allocation/server.cpp b/asio/src/examples/cpp03/allocation/server.cpp deleted file mode 100644 index 320b878afa..0000000000 --- a/asio/src/examples/cpp03/allocation/server.cpp +++ /dev/null @@ -1,242 +0,0 @@ -// -// server.cpp -// ~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include -#include -#include -#include -#include -#include -#include -#include -#include "asio.hpp" - -using asio::ip::tcp; - -// Class to manage the memory to be used for handler-based custom allocation. -// It contains a single block of memory which may be returned for allocation -// requests. If the memory is in use when an allocation request is made, the -// allocator delegates allocation to the global heap. -class handler_memory - : private boost::noncopyable -{ -public: - handler_memory() - : in_use_(false) - { - } - - void* allocate(std::size_t size) - { - if (!in_use_ && size < storage_.size) - { - in_use_ = true; - return storage_.address(); - } - else - { - return ::operator new(size); - } - } - - void deallocate(void* pointer) - { - if (pointer == storage_.address()) - { - in_use_ = false; - } - else - { - ::operator delete(pointer); - } - } - -private: - // Storage space used for handler-based custom memory allocation. - boost::aligned_storage<1024> storage_; - - // Whether the handler-based custom allocation storage has been used. - bool in_use_; -}; - -// The allocator to be associated with the handler objects. This allocator only -// needs to satisfy the C++11 minimal allocator requirements, plus rebind when -// targeting C++03. -template -class handler_allocator -{ -public: - typedef T value_type; - - explicit handler_allocator(handler_memory& mem) - : memory_(mem) - { - } - - template - handler_allocator(const handler_allocator& other) - : memory_(other.memory_) - { - } - - template - struct rebind - { - typedef handler_allocator other; - }; - - bool operator==(const handler_allocator& other) const - { - return &memory_ == &other.memory_; - } - - bool operator!=(const handler_allocator& other) const - { - return &memory_ != &other.memory_; - } - - T* allocate(std::size_t n) const - { - return static_cast(memory_.allocate(sizeof(T) * n)); - } - - void deallocate(T* p, std::size_t /*n*/) const - { - return memory_.deallocate(p); - } - -//private: - // The underlying memory. - handler_memory& memory_; -}; - -class session - : public boost::enable_shared_from_this -{ -public: - session(asio::io_context& io_context) - : socket_(io_context) - { - } - - tcp::socket& socket() - { - return socket_; - } - - void start() - { - socket_.async_read_some(asio::buffer(data_), - asio::bind_allocator( - handler_allocator(handler_memory_), - boost::bind(&session::handle_read, - shared_from_this(), - asio::placeholders::error, - asio::placeholders::bytes_transferred))); - } - - void handle_read(const asio::error_code& error, - size_t bytes_transferred) - { - if (!error) - { - asio::async_write(socket_, - asio::buffer(data_, bytes_transferred), - asio::bind_allocator( - handler_allocator(handler_memory_), - boost::bind(&session::handle_write, - shared_from_this(), - asio::placeholders::error))); - } - } - - void handle_write(const asio::error_code& error) - { - if (!error) - { - socket_.async_read_some(asio::buffer(data_), - asio::bind_allocator( - handler_allocator(handler_memory_), - boost::bind(&session::handle_read, - shared_from_this(), - asio::placeholders::error, - asio::placeholders::bytes_transferred))); - } - } - -private: - // The socket used to communicate with the client. - tcp::socket socket_; - - // Buffer used to store data received from the client. - boost::array data_; - - // The memory to use for handler-based custom memory allocation. - handler_memory handler_memory_; -}; - -typedef boost::shared_ptr session_ptr; - -class server -{ -public: - server(asio::io_context& io_context, short port) - : io_context_(io_context), - acceptor_(io_context, tcp::endpoint(tcp::v4(), port)) - { - session_ptr new_session(new session(io_context_)); - acceptor_.async_accept(new_session->socket(), - boost::bind(&server::handle_accept, this, new_session, - asio::placeholders::error)); - } - - void handle_accept(session_ptr new_session, - const asio::error_code& error) - { - if (!error) - { - new_session->start(); - } - - new_session.reset(new session(io_context_)); - acceptor_.async_accept(new_session->socket(), - boost::bind(&server::handle_accept, this, new_session, - asio::placeholders::error)); - } - -private: - asio::io_context& io_context_; - tcp::acceptor acceptor_; -}; - -int main(int argc, char* argv[]) -{ - try - { - if (argc != 2) - { - std::cerr << "Usage: server \n"; - return 1; - } - - asio::io_context io_context; - - using namespace std; // For atoi. - server s(io_context, atoi(argv[1])); - - io_context.run(); - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - } - - return 0; -} diff --git a/asio/src/examples/cpp03/buffers/.gitignore b/asio/src/examples/cpp03/buffers/.gitignore deleted file mode 100644 index abe68c665f..0000000000 --- a/asio/src/examples/cpp03/buffers/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -.deps -.dirstamp -*.o -*.obj -*.exe -reference_counted -*.ilk -*.manifest -*.pdb -*.tds diff --git a/asio/src/examples/cpp03/buffers/reference_counted.cpp b/asio/src/examples/cpp03/buffers/reference_counted.cpp deleted file mode 100644 index 82d737a9ca..0000000000 --- a/asio/src/examples/cpp03/buffers/reference_counted.cpp +++ /dev/null @@ -1,131 +0,0 @@ -// -// reference_counted.cpp -// ~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include -#include -#include -#include -#include -#include - -using asio::ip::tcp; - -// A reference-counted non-modifiable buffer class. -class shared_const_buffer -{ -public: - // Construct from a std::string. - explicit shared_const_buffer(const std::string& data) - : data_(new std::vector(data.begin(), data.end())), - buffer_(asio::buffer(*data_)) - { - } - - // Implement the ConstBufferSequence requirements. - typedef asio::const_buffer value_type; - typedef const asio::const_buffer* const_iterator; - const asio::const_buffer* begin() const { return &buffer_; } - const asio::const_buffer* end() const { return &buffer_ + 1; } - -private: - boost::shared_ptr > data_; - asio::const_buffer buffer_; -}; - -class session - : public boost::enable_shared_from_this -{ -public: - session(asio::io_context& io_context) - : socket_(io_context) - { - } - - tcp::socket& socket() - { - return socket_; - } - - void start() - { - using namespace std; // For time_t, time and ctime. - time_t now = time(0); - shared_const_buffer buffer(ctime(&now)); - asio::async_write(socket_, buffer, - boost::bind(&session::handle_write, shared_from_this())); - } - - void handle_write() - { - } - -private: - // The socket used to communicate with the client. - tcp::socket socket_; -}; - -typedef boost::shared_ptr session_ptr; - -class server -{ -public: - server(asio::io_context& io_context, short port) - : io_context_(io_context), - acceptor_(io_context, tcp::endpoint(tcp::v4(), port)) - { - session_ptr new_session(new session(io_context_)); - acceptor_.async_accept(new_session->socket(), - boost::bind(&server::handle_accept, this, new_session, - asio::placeholders::error)); - } - - void handle_accept(session_ptr new_session, - const asio::error_code& error) - { - if (!error) - { - new_session->start(); - } - - new_session.reset(new session(io_context_)); - acceptor_.async_accept(new_session->socket(), - boost::bind(&server::handle_accept, this, new_session, - asio::placeholders::error)); - } - -private: - asio::io_context& io_context_; - tcp::acceptor acceptor_; -}; - -int main(int argc, char* argv[]) -{ - try - { - if (argc != 2) - { - std::cerr << "Usage: reference_counted \n"; - return 1; - } - - asio::io_context io_context; - - using namespace std; // For atoi. - server s(io_context, atoi(argv[1])); - - io_context.run(); - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - } - - return 0; -} diff --git a/asio/src/examples/cpp03/chat/chat_client.cpp b/asio/src/examples/cpp03/chat/chat_client.cpp deleted file mode 100644 index 65305c603e..0000000000 --- a/asio/src/examples/cpp03/chat/chat_client.cpp +++ /dev/null @@ -1,177 +0,0 @@ -// -// chat_client.cpp -// ~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include -#include -#include -#include -#include "asio.hpp" -#include "chat_message.hpp" - -using asio::ip::tcp; - -typedef std::deque chat_message_queue; - -class chat_client -{ -public: - chat_client(asio::io_context& io_context, - const tcp::resolver::results_type& endpoints) - : io_context_(io_context), - socket_(io_context) - { - asio::async_connect(socket_, endpoints, - boost::bind(&chat_client::handle_connect, this, - asio::placeholders::error)); - } - - void write(const chat_message& msg) - { - asio::post(io_context_, - boost::bind(&chat_client::do_write, this, msg)); - } - - void close() - { - asio::post(io_context_, - boost::bind(&chat_client::do_close, this)); - } - -private: - - void handle_connect(const asio::error_code& error) - { - if (!error) - { - asio::async_read(socket_, - asio::buffer(read_msg_.data(), chat_message::header_length), - boost::bind(&chat_client::handle_read_header, this, - asio::placeholders::error)); - } - } - - void handle_read_header(const asio::error_code& error) - { - if (!error && read_msg_.decode_header()) - { - asio::async_read(socket_, - asio::buffer(read_msg_.body(), read_msg_.body_length()), - boost::bind(&chat_client::handle_read_body, this, - asio::placeholders::error)); - } - else - { - do_close(); - } - } - - void handle_read_body(const asio::error_code& error) - { - if (!error) - { - std::cout.write(read_msg_.body(), read_msg_.body_length()); - std::cout << "\n"; - asio::async_read(socket_, - asio::buffer(read_msg_.data(), chat_message::header_length), - boost::bind(&chat_client::handle_read_header, this, - asio::placeholders::error)); - } - else - { - do_close(); - } - } - - void do_write(chat_message msg) - { - bool write_in_progress = !write_msgs_.empty(); - write_msgs_.push_back(msg); - if (!write_in_progress) - { - asio::async_write(socket_, - asio::buffer(write_msgs_.front().data(), - write_msgs_.front().length()), - boost::bind(&chat_client::handle_write, this, - asio::placeholders::error)); - } - } - - void handle_write(const asio::error_code& error) - { - if (!error) - { - write_msgs_.pop_front(); - if (!write_msgs_.empty()) - { - asio::async_write(socket_, - asio::buffer(write_msgs_.front().data(), - write_msgs_.front().length()), - boost::bind(&chat_client::handle_write, this, - asio::placeholders::error)); - } - } - else - { - do_close(); - } - } - - void do_close() - { - socket_.close(); - } - -private: - asio::io_context& io_context_; - tcp::socket socket_; - chat_message read_msg_; - chat_message_queue write_msgs_; -}; - -int main(int argc, char* argv[]) -{ - try - { - if (argc != 3) - { - std::cerr << "Usage: chat_client \n"; - return 1; - } - - asio::io_context io_context; - - tcp::resolver resolver(io_context); - tcp::resolver::results_type endpoints = resolver.resolve(argv[1], argv[2]); - - chat_client c(io_context, endpoints); - - asio::thread t(boost::bind(&asio::io_context::run, &io_context)); - - char line[chat_message::max_body_length + 1]; - while (std::cin.getline(line, chat_message::max_body_length + 1)) - { - using namespace std; // For strlen and memcpy. - chat_message msg; - msg.body_length(strlen(line)); - memcpy(msg.body(), line, msg.body_length()); - msg.encode_header(); - c.write(msg); - } - - c.close(); - t.join(); - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - } - - return 0; -} diff --git a/asio/src/examples/cpp03/chat/chat_message.hpp b/asio/src/examples/cpp03/chat/chat_message.hpp deleted file mode 100644 index 0717054fd2..0000000000 --- a/asio/src/examples/cpp03/chat/chat_message.hpp +++ /dev/null @@ -1,96 +0,0 @@ -// -// chat_message.hpp -// ~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef CHAT_MESSAGE_HPP -#define CHAT_MESSAGE_HPP - -#include -#include -#include - -class chat_message -{ -public: - enum - { - header_length = 4, - max_body_length = 512 - }; - - chat_message() - : body_length_(0) - { - } - - const char* data() const - { - return data_; - } - - char* data() - { - return data_; - } - - size_t length() const - { - return header_length + body_length_; - } - - const char* body() const - { - return data_ + header_length; - } - - char* body() - { - return data_ + header_length; - } - - size_t body_length() const - { - return body_length_; - } - - void body_length(size_t new_length) - { - body_length_ = new_length; - if (body_length_ > max_body_length) - body_length_ = max_body_length; - } - - bool decode_header() - { - using namespace std; // For strncat and atoi. - char header[header_length + 1] = ""; - strncat(header, data_, header_length); - body_length_ = atoi(header); - if (body_length_ > max_body_length) - { - body_length_ = 0; - return false; - } - return true; - } - - void encode_header() - { - using namespace std; // For sprintf and memcpy. - char header[header_length + 1] = ""; - sprintf(header, "%4d", static_cast(body_length_)); - memcpy(data_, header, header_length); - } - -private: - char data_[header_length + max_body_length]; - size_t body_length_; -}; - -#endif // CHAT_MESSAGE_HPP diff --git a/asio/src/examples/cpp03/chat/chat_server.cpp b/asio/src/examples/cpp03/chat/chat_server.cpp deleted file mode 100644 index 4d2b5aaf71..0000000000 --- a/asio/src/examples/cpp03/chat/chat_server.cpp +++ /dev/null @@ -1,249 +0,0 @@ -// -// chat_server.cpp -// ~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "asio.hpp" -#include "chat_message.hpp" - -using asio::ip::tcp; - -//---------------------------------------------------------------------- - -typedef std::deque chat_message_queue; - -//---------------------------------------------------------------------- - -class chat_participant -{ -public: - virtual ~chat_participant() {} - virtual void deliver(const chat_message& msg) = 0; -}; - -typedef boost::shared_ptr chat_participant_ptr; - -//---------------------------------------------------------------------- - -class chat_room -{ -public: - void join(chat_participant_ptr participant) - { - participants_.insert(participant); - std::for_each(recent_msgs_.begin(), recent_msgs_.end(), - boost::bind(&chat_participant::deliver, - participant, boost::placeholders::_1)); - } - - void leave(chat_participant_ptr participant) - { - participants_.erase(participant); - } - - void deliver(const chat_message& msg) - { - recent_msgs_.push_back(msg); - while (recent_msgs_.size() > max_recent_msgs) - recent_msgs_.pop_front(); - - std::for_each(participants_.begin(), participants_.end(), - boost::bind(&chat_participant::deliver, - boost::placeholders::_1, boost::ref(msg))); - } - -private: - std::set participants_; - enum { max_recent_msgs = 100 }; - chat_message_queue recent_msgs_; -}; - -//---------------------------------------------------------------------- - -class chat_session - : public chat_participant, - public boost::enable_shared_from_this -{ -public: - chat_session(asio::io_context& io_context, chat_room& room) - : socket_(io_context), - room_(room) - { - } - - tcp::socket& socket() - { - return socket_; - } - - void start() - { - room_.join(shared_from_this()); - asio::async_read(socket_, - asio::buffer(read_msg_.data(), chat_message::header_length), - boost::bind( - &chat_session::handle_read_header, shared_from_this(), - asio::placeholders::error)); - } - - void deliver(const chat_message& msg) - { - bool write_in_progress = !write_msgs_.empty(); - write_msgs_.push_back(msg); - if (!write_in_progress) - { - asio::async_write(socket_, - asio::buffer(write_msgs_.front().data(), - write_msgs_.front().length()), - boost::bind(&chat_session::handle_write, shared_from_this(), - asio::placeholders::error)); - } - } - - void handle_read_header(const asio::error_code& error) - { - if (!error && read_msg_.decode_header()) - { - asio::async_read(socket_, - asio::buffer(read_msg_.body(), read_msg_.body_length()), - boost::bind(&chat_session::handle_read_body, shared_from_this(), - asio::placeholders::error)); - } - else - { - room_.leave(shared_from_this()); - } - } - - void handle_read_body(const asio::error_code& error) - { - if (!error) - { - room_.deliver(read_msg_); - asio::async_read(socket_, - asio::buffer(read_msg_.data(), chat_message::header_length), - boost::bind(&chat_session::handle_read_header, shared_from_this(), - asio::placeholders::error)); - } - else - { - room_.leave(shared_from_this()); - } - } - - void handle_write(const asio::error_code& error) - { - if (!error) - { - write_msgs_.pop_front(); - if (!write_msgs_.empty()) - { - asio::async_write(socket_, - asio::buffer(write_msgs_.front().data(), - write_msgs_.front().length()), - boost::bind(&chat_session::handle_write, shared_from_this(), - asio::placeholders::error)); - } - } - else - { - room_.leave(shared_from_this()); - } - } - -private: - tcp::socket socket_; - chat_room& room_; - chat_message read_msg_; - chat_message_queue write_msgs_; -}; - -typedef boost::shared_ptr chat_session_ptr; - -//---------------------------------------------------------------------- - -class chat_server -{ -public: - chat_server(asio::io_context& io_context, - const tcp::endpoint& endpoint) - : io_context_(io_context), - acceptor_(io_context, endpoint) - { - start_accept(); - } - - void start_accept() - { - chat_session_ptr new_session(new chat_session(io_context_, room_)); - acceptor_.async_accept(new_session->socket(), - boost::bind(&chat_server::handle_accept, this, new_session, - asio::placeholders::error)); - } - - void handle_accept(chat_session_ptr session, - const asio::error_code& error) - { - if (!error) - { - session->start(); - } - - start_accept(); - } - -private: - asio::io_context& io_context_; - tcp::acceptor acceptor_; - chat_room room_; -}; - -typedef boost::shared_ptr chat_server_ptr; -typedef std::list chat_server_list; - -//---------------------------------------------------------------------- - -int main(int argc, char* argv[]) -{ - try - { - if (argc < 2) - { - std::cerr << "Usage: chat_server [ ...]\n"; - return 1; - } - - asio::io_context io_context; - - chat_server_list servers; - for (int i = 1; i < argc; ++i) - { - using namespace std; // For atoi. - tcp::endpoint endpoint(tcp::v4(), atoi(argv[i])); - chat_server_ptr server(new chat_server(io_context, endpoint)); - servers.push_back(server); - } - - io_context.run(); - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - } - - return 0; -} diff --git a/asio/src/examples/cpp03/chat/posix_chat_client.cpp b/asio/src/examples/cpp03/chat/posix_chat_client.cpp deleted file mode 100644 index a579eac221..0000000000 --- a/asio/src/examples/cpp03/chat/posix_chat_client.cpp +++ /dev/null @@ -1,204 +0,0 @@ -// -// posix_chat_client.cpp -// ~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include -#include -#include -#include -#include -#include "asio.hpp" -#include "chat_message.hpp" - -#if defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) - -using asio::ip::tcp; -namespace posix = asio::posix; - -class posix_chat_client -{ -public: - posix_chat_client(asio::io_context& io_context, - const tcp::resolver::results_type& endpoints) - : socket_(io_context), - input_(io_context, ::dup(STDIN_FILENO)), - output_(io_context, ::dup(STDOUT_FILENO)), - input_buffer_(chat_message::max_body_length) - { - asio::async_connect(socket_, endpoints, - boost::bind(&posix_chat_client::handle_connect, this, - asio::placeholders::error)); - } - -private: - - void handle_connect(const asio::error_code& error) - { - if (!error) - { - // Read the fixed-length header of the next message from the server. - asio::async_read(socket_, - asio::buffer(read_msg_.data(), chat_message::header_length), - boost::bind(&posix_chat_client::handle_read_header, this, - asio::placeholders::error)); - - // Read a line of input entered by the user. - asio::async_read_until(input_, input_buffer_, '\n', - boost::bind(&posix_chat_client::handle_read_input, this, - asio::placeholders::error, - asio::placeholders::bytes_transferred)); - } - } - - void handle_read_header(const asio::error_code& error) - { - if (!error && read_msg_.decode_header()) - { - // Read the variable-length body of the message from the server. - asio::async_read(socket_, - asio::buffer(read_msg_.body(), read_msg_.body_length()), - boost::bind(&posix_chat_client::handle_read_body, this, - asio::placeholders::error)); - } - else - { - close(); - } - } - - void handle_read_body(const asio::error_code& error) - { - if (!error) - { - // Write out the message we just received, terminated by a newline. - static char eol[] = { '\n' }; - boost::array buffers = {{ - asio::buffer(read_msg_.body(), read_msg_.body_length()), - asio::buffer(eol) }}; - asio::async_write(output_, buffers, - boost::bind(&posix_chat_client::handle_write_output, this, - asio::placeholders::error)); - } - else - { - close(); - } - } - - void handle_write_output(const asio::error_code& error) - { - if (!error) - { - // Read the fixed-length header of the next message from the server. - asio::async_read(socket_, - asio::buffer(read_msg_.data(), chat_message::header_length), - boost::bind(&posix_chat_client::handle_read_header, this, - asio::placeholders::error)); - } - else - { - close(); - } - } - - void handle_read_input(const asio::error_code& error, - std::size_t length) - { - if (!error) - { - // Write the message (minus the newline) to the server. - write_msg_.body_length(length - 1); - input_buffer_.sgetn(write_msg_.body(), length - 1); - input_buffer_.consume(1); // Remove newline from input. - write_msg_.encode_header(); - asio::async_write(socket_, - asio::buffer(write_msg_.data(), write_msg_.length()), - boost::bind(&posix_chat_client::handle_write, this, - asio::placeholders::error)); - } - else if (error == asio::error::not_found) - { - // Didn't get a newline. Send whatever we have. - write_msg_.body_length(input_buffer_.size()); - input_buffer_.sgetn(write_msg_.body(), input_buffer_.size()); - write_msg_.encode_header(); - asio::async_write(socket_, - asio::buffer(write_msg_.data(), write_msg_.length()), - boost::bind(&posix_chat_client::handle_write, this, - asio::placeholders::error)); - } - else - { - close(); - } - } - - void handle_write(const asio::error_code& error) - { - if (!error) - { - // Read a line of input entered by the user. - asio::async_read_until(input_, input_buffer_, '\n', - boost::bind(&posix_chat_client::handle_read_input, this, - asio::placeholders::error, - asio::placeholders::bytes_transferred)); - } - else - { - close(); - } - } - - void close() - { - // Cancel all outstanding asynchronous operations. - socket_.close(); - input_.close(); - output_.close(); - } - -private: - tcp::socket socket_; - posix::stream_descriptor input_; - posix::stream_descriptor output_; - chat_message read_msg_; - chat_message write_msg_; - asio::streambuf input_buffer_; -}; - -int main(int argc, char* argv[]) -{ - try - { - if (argc != 3) - { - std::cerr << "Usage: posix_chat_client \n"; - return 1; - } - - asio::io_context io_context; - - tcp::resolver resolver(io_context); - tcp::resolver::results_type endpoints = resolver.resolve(argv[1], argv[2]); - - posix_chat_client c(io_context, endpoints); - - io_context.run(); - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - } - - return 0; -} - -#else // defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) -int main() {} -#endif // defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) diff --git a/asio/src/examples/cpp03/echo/async_tcp_echo_server.cpp b/asio/src/examples/cpp03/echo/async_tcp_echo_server.cpp deleted file mode 100644 index cfafc674aa..0000000000 --- a/asio/src/examples/cpp03/echo/async_tcp_echo_server.cpp +++ /dev/null @@ -1,137 +0,0 @@ -// -// async_tcp_echo_server.cpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include -#include -#include -#include "asio.hpp" - -using asio::ip::tcp; - -class session -{ -public: - session(asio::io_context& io_context) - : socket_(io_context) - { - } - - tcp::socket& socket() - { - return socket_; - } - - void start() - { - socket_.async_read_some(asio::buffer(data_, max_length), - boost::bind(&session::handle_read, this, - asio::placeholders::error, - asio::placeholders::bytes_transferred)); - } - -private: - void handle_read(const asio::error_code& error, - size_t bytes_transferred) - { - if (!error) - { - asio::async_write(socket_, - asio::buffer(data_, bytes_transferred), - boost::bind(&session::handle_write, this, - asio::placeholders::error)); - } - else - { - delete this; - } - } - - void handle_write(const asio::error_code& error) - { - if (!error) - { - socket_.async_read_some(asio::buffer(data_, max_length), - boost::bind(&session::handle_read, this, - asio::placeholders::error, - asio::placeholders::bytes_transferred)); - } - else - { - delete this; - } - } - - tcp::socket socket_; - enum { max_length = 1024 }; - char data_[max_length]; -}; - -class server -{ -public: - server(asio::io_context& io_context, short port) - : io_context_(io_context), - acceptor_(io_context, tcp::endpoint(tcp::v4(), port)) - { - start_accept(); - } - -private: - void start_accept() - { - session* new_session = new session(io_context_); - acceptor_.async_accept(new_session->socket(), - boost::bind(&server::handle_accept, this, new_session, - asio::placeholders::error)); - } - - void handle_accept(session* new_session, - const asio::error_code& error) - { - if (!error) - { - new_session->start(); - } - else - { - delete new_session; - } - - start_accept(); - } - - asio::io_context& io_context_; - tcp::acceptor acceptor_; -}; - -int main(int argc, char* argv[]) -{ - try - { - if (argc != 2) - { - std::cerr << "Usage: async_tcp_echo_server \n"; - return 1; - } - - asio::io_context io_context; - - using namespace std; // For atoi. - server s(io_context, atoi(argv[1])); - - io_context.run(); - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - } - - return 0; -} diff --git a/asio/src/examples/cpp03/echo/async_udp_echo_server.cpp b/asio/src/examples/cpp03/echo/async_udp_echo_server.cpp deleted file mode 100644 index d0202324bc..0000000000 --- a/asio/src/examples/cpp03/echo/async_udp_echo_server.cpp +++ /dev/null @@ -1,92 +0,0 @@ -// -// async_udp_echo_server.cpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include -#include -#include -#include "asio.hpp" - -using asio::ip::udp; - -class server -{ -public: - server(asio::io_context& io_context, short port) - : socket_(io_context, udp::endpoint(udp::v4(), port)) - { - socket_.async_receive_from( - asio::buffer(data_, max_length), sender_endpoint_, - boost::bind(&server::handle_receive_from, this, - asio::placeholders::error, - asio::placeholders::bytes_transferred)); - } - - void handle_receive_from(const asio::error_code& error, - size_t bytes_recvd) - { - if (!error && bytes_recvd > 0) - { - socket_.async_send_to( - asio::buffer(data_, bytes_recvd), sender_endpoint_, - boost::bind(&server::handle_send_to, this, - asio::placeholders::error, - asio::placeholders::bytes_transferred)); - } - else - { - socket_.async_receive_from( - asio::buffer(data_, max_length), sender_endpoint_, - boost::bind(&server::handle_receive_from, this, - asio::placeholders::error, - asio::placeholders::bytes_transferred)); - } - } - - void handle_send_to(const asio::error_code& /*error*/, - size_t /*bytes_sent*/) - { - socket_.async_receive_from( - asio::buffer(data_, max_length), sender_endpoint_, - boost::bind(&server::handle_receive_from, this, - asio::placeholders::error, - asio::placeholders::bytes_transferred)); - } - -private: - udp::socket socket_; - udp::endpoint sender_endpoint_; - enum { max_length = 1024 }; - char data_[max_length]; -}; - -int main(int argc, char* argv[]) -{ - try - { - if (argc != 2) - { - std::cerr << "Usage: async_udp_echo_server \n"; - return 1; - } - - asio::io_context io_context; - - using namespace std; // For atoi. - server s(io_context, atoi(argv[1])); - - io_context.run(); - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - } - - return 0; -} diff --git a/asio/src/examples/cpp03/echo/blocking_tcp_echo_client.cpp b/asio/src/examples/cpp03/echo/blocking_tcp_echo_client.cpp deleted file mode 100644 index b7a02b661f..0000000000 --- a/asio/src/examples/cpp03/echo/blocking_tcp_echo_client.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// -// blocking_tcp_echo_client.cpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include -#include -#include -#include "asio.hpp" - -using asio::ip::tcp; - -enum { max_length = 1024 }; - -int main(int argc, char* argv[]) -{ - try - { - if (argc != 3) - { - std::cerr << "Usage: blocking_tcp_echo_client \n"; - return 1; - } - - asio::io_context io_context; - - tcp::resolver resolver(io_context); - tcp::resolver::results_type endpoints = - resolver.resolve(tcp::v4(), argv[1], argv[2]); - - tcp::socket s(io_context); - asio::connect(s, endpoints); - - using namespace std; // For strlen. - std::cout << "Enter message: "; - char request[max_length]; - std::cin.getline(request, max_length); - size_t request_length = strlen(request); - asio::write(s, asio::buffer(request, request_length)); - - char reply[max_length]; - size_t reply_length = asio::read(s, - asio::buffer(reply, request_length)); - std::cout << "Reply is: "; - std::cout.write(reply, reply_length); - std::cout << "\n"; - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - } - - return 0; -} diff --git a/asio/src/examples/cpp03/echo/blocking_tcp_echo_server.cpp b/asio/src/examples/cpp03/echo/blocking_tcp_echo_server.cpp deleted file mode 100644 index 417e38b287..0000000000 --- a/asio/src/examples/cpp03/echo/blocking_tcp_echo_server.cpp +++ /dev/null @@ -1,79 +0,0 @@ -// -// blocking_tcp_echo_server.cpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include -#include -#include -#include -#include "asio.hpp" - -using asio::ip::tcp; - -const int max_length = 1024; - -typedef boost::shared_ptr socket_ptr; - -void session(socket_ptr sock) -{ - try - { - for (;;) - { - char data[max_length]; - - asio::error_code error; - size_t length = sock->read_some(asio::buffer(data), error); - if (error == asio::error::eof) - break; // Connection closed cleanly by peer. - else if (error) - throw asio::system_error(error); // Some other error. - - asio::write(*sock, asio::buffer(data, length)); - } - } - catch (std::exception& e) - { - std::cerr << "Exception in thread: " << e.what() << "\n"; - } -} - -void server(asio::io_context& io_context, unsigned short port) -{ - tcp::acceptor a(io_context, tcp::endpoint(tcp::v4(), port)); - for (;;) - { - socket_ptr sock(new tcp::socket(io_context)); - a.accept(*sock); - asio::thread t(boost::bind(session, sock)); - } -} - -int main(int argc, char* argv[]) -{ - try - { - if (argc != 2) - { - std::cerr << "Usage: blocking_tcp_echo_server \n"; - return 1; - } - - asio::io_context io_context; - - using namespace std; // For atoi. - server(io_context, atoi(argv[1])); - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - } - - return 0; -} diff --git a/asio/src/examples/cpp03/echo/blocking_udp_echo_client.cpp b/asio/src/examples/cpp03/echo/blocking_udp_echo_client.cpp deleted file mode 100644 index d9b1ad71bb..0000000000 --- a/asio/src/examples/cpp03/echo/blocking_udp_echo_client.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// -// blocking_udp_echo_client.cpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include -#include -#include -#include "asio.hpp" - -using asio::ip::udp; - -enum { max_length = 1024 }; - -int main(int argc, char* argv[]) -{ - try - { - if (argc != 3) - { - std::cerr << "Usage: blocking_udp_echo_client \n"; - return 1; - } - - asio::io_context io_context; - - udp::socket s(io_context, udp::endpoint(udp::v4(), 0)); - - udp::resolver resolver(io_context); - udp::resolver::results_type endpoints = - resolver.resolve(udp::v4(), argv[1], argv[2]); - - using namespace std; // For strlen. - std::cout << "Enter message: "; - char request[max_length]; - std::cin.getline(request, max_length); - size_t request_length = strlen(request); - s.send_to(asio::buffer(request, request_length), *endpoints.begin()); - - char reply[max_length]; - udp::endpoint sender_endpoint; - size_t reply_length = s.receive_from( - asio::buffer(reply, max_length), sender_endpoint); - std::cout << "Reply is: "; - std::cout.write(reply, reply_length); - std::cout << "\n"; - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - } - - return 0; -} diff --git a/asio/src/examples/cpp03/echo/blocking_udp_echo_server.cpp b/asio/src/examples/cpp03/echo/blocking_udp_echo_server.cpp deleted file mode 100644 index aa223aa7c1..0000000000 --- a/asio/src/examples/cpp03/echo/blocking_udp_echo_server.cpp +++ /dev/null @@ -1,53 +0,0 @@ -// -// blocking_udp_echo_server.cpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include -#include -#include "asio.hpp" - -using asio::ip::udp; - -enum { max_length = 1024 }; - -void server(asio::io_context& io_context, unsigned short port) -{ - udp::socket sock(io_context, udp::endpoint(udp::v4(), port)); - for (;;) - { - char data[max_length]; - udp::endpoint sender_endpoint; - size_t length = sock.receive_from( - asio::buffer(data, max_length), sender_endpoint); - sock.send_to(asio::buffer(data, length), sender_endpoint); - } -} - -int main(int argc, char* argv[]) -{ - try - { - if (argc != 2) - { - std::cerr << "Usage: blocking_udp_echo_server \n"; - return 1; - } - - asio::io_context io_context; - - using namespace std; // For atoi. - server(io_context, atoi(argv[1])); - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - } - - return 0; -} diff --git a/asio/src/examples/cpp03/fork/.gitignore b/asio/src/examples/cpp03/fork/.gitignore deleted file mode 100644 index 6b565fe313..0000000000 --- a/asio/src/examples/cpp03/fork/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -.deps -.dirstamp -*.o -*.obj -*.exe -*.ilk -*.manifest -*.pdb -*.tds -daemon -process_per_connection diff --git a/asio/src/examples/cpp03/fork/daemon.cpp b/asio/src/examples/cpp03/fork/daemon.cpp deleted file mode 100644 index d0f98fdf75..0000000000 --- a/asio/src/examples/cpp03/fork/daemon.cpp +++ /dev/null @@ -1,190 +0,0 @@ -// -// daemon.cpp -// ~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using asio::ip::udp; - -class udp_daytime_server -{ -public: - udp_daytime_server(asio::io_context& io_context) - : socket_(io_context, udp::endpoint(udp::v4(), 13)) - { - start_receive(); - } - -private: - void start_receive() - { - socket_.async_receive_from( - asio::buffer(recv_buffer_), remote_endpoint_, - boost::bind(&udp_daytime_server::handle_receive, - this, boost::placeholders::_1)); - } - - void handle_receive(const asio::error_code& ec) - { - if (!ec) - { - using namespace std; // For time_t, time and ctime; - time_t now = time(0); - std::string message = ctime(&now); - - asio::error_code ignored_ec; - socket_.send_to(asio::buffer(message), - remote_endpoint_, 0, ignored_ec); - } - - start_receive(); - } - - udp::socket socket_; - udp::endpoint remote_endpoint_; - boost::array recv_buffer_; -}; - -int main() -{ - try - { - asio::io_context io_context; - - // Initialise the server before becoming a daemon. If the process is - // started from a shell, this means any errors will be reported back to the - // user. - udp_daytime_server server(io_context); - - // Register signal handlers so that the daemon may be shut down. You may - // also want to register for other signals, such as SIGHUP to trigger a - // re-read of a configuration file. - asio::signal_set signals(io_context, SIGINT, SIGTERM); - signals.async_wait( - boost::bind(&asio::io_context::stop, &io_context)); - - // Inform the io_context that we are about to become a daemon. The - // io_context cleans up any internal resources, such as threads, that may - // interfere with forking. - io_context.notify_fork(asio::io_context::fork_prepare); - - // Fork the process and have the parent exit. If the process was started - // from a shell, this returns control to the user. Forking a new process is - // also a prerequisite for the subsequent call to setsid(). - if (pid_t pid = fork()) - { - if (pid > 0) - { - // We're in the parent process and need to exit. - // - // When the exit() function is used, the program terminates without - // invoking local variables' destructors. Only global variables are - // destroyed. As the io_context object is a local variable, this means - // we do not have to call: - // - // io_context.notify_fork(asio::io_context::fork_parent); - // - // However, this line should be added before each call to exit() if - // using a global io_context object. An additional call: - // - // io_context.notify_fork(asio::io_context::fork_prepare); - // - // should also precede the second fork(). - exit(0); - } - else - { - syslog(LOG_ERR | LOG_USER, "First fork failed: %m"); - return 1; - } - } - - // Make the process a new session leader. This detaches it from the - // terminal. - setsid(); - - // A process inherits its working directory from its parent. This could be - // on a mounted filesystem, which means that the running daemon would - // prevent this filesystem from being unmounted. Changing to the root - // directory avoids this problem. - chdir("/"); - - // The file mode creation mask is also inherited from the parent process. - // We don't want to restrict the permissions on files created by the - // daemon, so the mask is cleared. - umask(0); - - // A second fork ensures the process cannot acquire a controlling terminal. - if (pid_t pid = fork()) - { - if (pid > 0) - { - exit(0); - } - else - { - syslog(LOG_ERR | LOG_USER, "Second fork failed: %m"); - return 1; - } - } - - // Close the standard streams. This decouples the daemon from the terminal - // that started it. - close(0); - close(1); - close(2); - - // We don't want the daemon to have any standard input. - if (open("/dev/null", O_RDONLY) < 0) - { - syslog(LOG_ERR | LOG_USER, "Unable to open /dev/null: %m"); - return 1; - } - - // Send standard output to a log file. - const char* output = "/tmp/asio.daemon.out"; - const int flags = O_WRONLY | O_CREAT | O_APPEND; - const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; - if (open(output, flags, mode) < 0) - { - syslog(LOG_ERR | LOG_USER, "Unable to open output file %s: %m", output); - return 1; - } - - // Also send standard error to the same log file. - if (dup(1) < 0) - { - syslog(LOG_ERR | LOG_USER, "Unable to dup output descriptor: %m"); - return 1; - } - - // Inform the io_context that we have finished becoming a daemon. The - // io_context uses this opportunity to create any internal file descriptors - // that need to be private to the new process. - io_context.notify_fork(asio::io_context::fork_child); - - // The io_context can now be used normally. - syslog(LOG_INFO | LOG_USER, "Daemon started"); - io_context.run(); - syslog(LOG_INFO | LOG_USER, "Daemon stopped"); - } - catch (std::exception& e) - { - syslog(LOG_ERR | LOG_USER, "Exception: %s", e.what()); - std::cerr << "Exception: " << e.what() << std::endl; - } -} diff --git a/asio/src/examples/cpp03/fork/process_per_connection.cpp b/asio/src/examples/cpp03/fork/process_per_connection.cpp deleted file mode 100644 index 5b853b4941..0000000000 --- a/asio/src/examples/cpp03/fork/process_per_connection.cpp +++ /dev/null @@ -1,161 +0,0 @@ -// -// process_per_connection.cpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using asio::ip::tcp; - -class server -{ -public: - server(asio::io_context& io_context, unsigned short port) - : io_context_(io_context), - signal_(io_context, SIGCHLD), - acceptor_(io_context, tcp::endpoint(tcp::v4(), port)), - socket_(io_context) - { - start_signal_wait(); - start_accept(); - } - -private: - void start_signal_wait() - { - signal_.async_wait(boost::bind(&server::handle_signal_wait, this)); - } - - void handle_signal_wait() - { - // Only the parent process should check for this signal. We can determine - // whether we are in the parent by checking if the acceptor is still open. - if (acceptor_.is_open()) - { - // Reap completed child processes so that we don't end up with zombies. - int status = 0; - while (waitpid(-1, &status, WNOHANG) > 0) {} - - start_signal_wait(); - } - } - - void start_accept() - { - acceptor_.async_accept(socket_, - boost::bind(&server::handle_accept, this, boost::placeholders::_1)); - } - - void handle_accept(const asio::error_code& ec) - { - if (!ec) - { - // Inform the io_context that we are about to fork. The io_context cleans - // up any internal resources, such as threads, that may interfere with - // forking. - io_context_.notify_fork(asio::io_context::fork_prepare); - - if (fork() == 0) - { - // Inform the io_context that the fork is finished and that this is the - // child process. The io_context uses this opportunity to create any - // internal file descriptors that must be private to the new process. - io_context_.notify_fork(asio::io_context::fork_child); - - // The child won't be accepting new connections, so we can close the - // acceptor. It remains open in the parent. - acceptor_.close(); - - // The child process is not interested in processing the SIGCHLD signal. - signal_.cancel(); - - start_read(); - } - else - { - // Inform the io_context that the fork is finished (or failed) and that - // this is the parent process. The io_context uses this opportunity to - // recreate any internal resources that were cleaned up during - // preparation for the fork. - io_context_.notify_fork(asio::io_context::fork_parent); - - socket_.close(); - start_accept(); - } - } - else - { - std::cerr << "Accept error: " << ec.message() << std::endl; - start_accept(); - } - } - - void start_read() - { - socket_.async_read_some(asio::buffer(data_), - boost::bind(&server::handle_read, this, - boost::placeholders::_1, boost::placeholders::_2)); - } - - void handle_read(const asio::error_code& ec, std::size_t length) - { - if (!ec) - start_write(length); - } - - void start_write(std::size_t length) - { - asio::async_write(socket_, asio::buffer(data_, length), - boost::bind(&server::handle_write, this, boost::placeholders::_1)); - } - - void handle_write(const asio::error_code& ec) - { - if (!ec) - start_read(); - } - - asio::io_context& io_context_; - asio::signal_set signal_; - tcp::acceptor acceptor_; - tcp::socket socket_; - boost::array data_; -}; - -int main(int argc, char* argv[]) -{ - try - { - if (argc != 2) - { - std::cerr << "Usage: process_per_connection \n"; - return 1; - } - - asio::io_context io_context; - - using namespace std; // For atoi. - server s(io_context, atoi(argv[1])); - - io_context.run(); - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << std::endl; - } -} diff --git a/asio/src/examples/cpp03/http/server/connection.cpp b/asio/src/examples/cpp03/http/server/connection.cpp deleted file mode 100644 index f8666d3e35..0000000000 --- a/asio/src/examples/cpp03/http/server/connection.cpp +++ /dev/null @@ -1,99 +0,0 @@ -// -// connection.cpp -// ~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include "connection.hpp" -#include -#include -#include "connection_manager.hpp" -#include "request_handler.hpp" - -namespace http { -namespace server { - -connection::connection(asio::io_context& io_context, - connection_manager& manager, request_handler& handler) - : socket_(io_context), - connection_manager_(manager), - request_handler_(handler) -{ -} - -asio::ip::tcp::socket& connection::socket() -{ - return socket_; -} - -void connection::start() -{ - socket_.async_read_some(asio::buffer(buffer_), - boost::bind(&connection::handle_read, shared_from_this(), - asio::placeholders::error, - asio::placeholders::bytes_transferred)); -} - -void connection::stop() -{ - socket_.close(); -} - -void connection::handle_read(const asio::error_code& e, - std::size_t bytes_transferred) -{ - if (!e) - { - boost::tribool result; - boost::tie(result, boost::tuples::ignore) = request_parser_.parse( - request_, buffer_.data(), buffer_.data() + bytes_transferred); - - if (result) - { - request_handler_.handle_request(request_, reply_); - asio::async_write(socket_, reply_.to_buffers(), - boost::bind(&connection::handle_write, shared_from_this(), - asio::placeholders::error)); - } - else if (!result) - { - reply_ = reply::stock_reply(reply::bad_request); - asio::async_write(socket_, reply_.to_buffers(), - boost::bind(&connection::handle_write, shared_from_this(), - asio::placeholders::error)); - } - else - { - socket_.async_read_some(asio::buffer(buffer_), - boost::bind(&connection::handle_read, shared_from_this(), - asio::placeholders::error, - asio::placeholders::bytes_transferred)); - } - } - else if (e != asio::error::operation_aborted) - { - connection_manager_.stop(shared_from_this()); - } -} - -void connection::handle_write(const asio::error_code& e) -{ - if (!e) - { - // Initiate graceful connection closure. - asio::error_code ignored_ec; - socket_.shutdown(asio::ip::tcp::socket::shutdown_both, ignored_ec); - } - - if (e != asio::error::operation_aborted) - { - connection_manager_.stop(shared_from_this()); - } -} - -} // namespace server -} // namespace http diff --git a/asio/src/examples/cpp03/http/server/connection.hpp b/asio/src/examples/cpp03/http/server/connection.hpp deleted file mode 100644 index be89e0a85a..0000000000 --- a/asio/src/examples/cpp03/http/server/connection.hpp +++ /dev/null @@ -1,83 +0,0 @@ -// -// connection.hpp -// ~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef HTTP_CONNECTION_HPP -#define HTTP_CONNECTION_HPP - -#include -#include -#include -#include -#include -#include "reply.hpp" -#include "request.hpp" -#include "request_handler.hpp" -#include "request_parser.hpp" - -namespace http { -namespace server { - -class connection_manager; - -/// Represents a single connection from a client. -class connection - : public boost::enable_shared_from_this, - private boost::noncopyable -{ -public: - /// Construct a connection with the given io_context. - explicit connection(asio::io_context& io_context, - connection_manager& manager, request_handler& handler); - - /// Get the socket associated with the connection. - asio::ip::tcp::socket& socket(); - - /// Start the first asynchronous operation for the connection. - void start(); - - /// Stop all asynchronous operations associated with the connection. - void stop(); - -private: - /// Handle completion of a read operation. - void handle_read(const asio::error_code& e, - std::size_t bytes_transferred); - - /// Handle completion of a write operation. - void handle_write(const asio::error_code& e); - - /// Socket for the connection. - asio::ip::tcp::socket socket_; - - /// The manager for this connection. - connection_manager& connection_manager_; - - /// The handler used to process the incoming request. - request_handler& request_handler_; - - /// Buffer for incoming data. - boost::array buffer_; - - /// The incoming request. - request request_; - - /// The parser for the incoming request. - request_parser request_parser_; - - /// The reply to be sent back to the client. - reply reply_; -}; - -typedef boost::shared_ptr connection_ptr; - -} // namespace server -} // namespace http - -#endif // HTTP_CONNECTION_HPP diff --git a/asio/src/examples/cpp03/http/server/connection_manager.cpp b/asio/src/examples/cpp03/http/server/connection_manager.cpp deleted file mode 100644 index 001acab343..0000000000 --- a/asio/src/examples/cpp03/http/server/connection_manager.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// -// connection_manager.cpp -// ~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include "connection_manager.hpp" -#include -#include - -namespace http { -namespace server { - -void connection_manager::start(connection_ptr c) -{ - connections_.insert(c); - c->start(); -} - -void connection_manager::stop(connection_ptr c) -{ - connections_.erase(c); - c->stop(); -} - -void connection_manager::stop_all() -{ - std::for_each(connections_.begin(), connections_.end(), - boost::bind(&connection::stop, boost::placeholders::_1)); - connections_.clear(); -} - -} // namespace server -} // namespace http diff --git a/asio/src/examples/cpp03/http/server/connection_manager.hpp b/asio/src/examples/cpp03/http/server/connection_manager.hpp deleted file mode 100644 index d806ad226c..0000000000 --- a/asio/src/examples/cpp03/http/server/connection_manager.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// -// connection_manager.hpp -// ~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef HTTP_CONNECTION_MANAGER_HPP -#define HTTP_CONNECTION_MANAGER_HPP - -#include -#include -#include "connection.hpp" - -namespace http { -namespace server { - -/// Manages open connections so that they may be cleanly stopped when the server -/// needs to shut down. -class connection_manager - : private boost::noncopyable -{ -public: - /// Add the specified connection to the manager and start it. - void start(connection_ptr c); - - /// Stop the specified connection. - void stop(connection_ptr c); - - /// Stop all connections. - void stop_all(); - -private: - /// The managed connections. - std::set connections_; -}; - -} // namespace server -} // namespace http - -#endif // HTTP_CONNECTION_MANAGER_HPP diff --git a/asio/src/examples/cpp03/http/server/header.hpp b/asio/src/examples/cpp03/http/server/header.hpp deleted file mode 100644 index 21ddfc47e4..0000000000 --- a/asio/src/examples/cpp03/http/server/header.hpp +++ /dev/null @@ -1,28 +0,0 @@ -// -// header.hpp -// ~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef HTTP_HEADER_HPP -#define HTTP_HEADER_HPP - -#include - -namespace http { -namespace server { - -struct header -{ - std::string name; - std::string value; -}; - -} // namespace server -} // namespace http - -#endif // HTTP_HEADER_HPP diff --git a/asio/src/examples/cpp03/http/server/main.cpp b/asio/src/examples/cpp03/http/server/main.cpp deleted file mode 100644 index a649cb0351..0000000000 --- a/asio/src/examples/cpp03/http/server/main.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// -// main.cpp -// ~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include -#include -#include -#include -#include "server.hpp" - -int main(int argc, char* argv[]) -{ - try - { - // Check command line arguments. - if (argc != 4) - { - std::cerr << "Usage: http_server
\n"; - std::cerr << " For IPv4, try:\n"; - std::cerr << " receiver 0.0.0.0 80 .\n"; - std::cerr << " For IPv6, try:\n"; - std::cerr << " receiver 0::0 80 .\n"; - return 1; - } - - // Initialise the server. - http::server::server s(argv[1], argv[2], argv[3]); - - // Run the server until stopped. - s.run(); - } - catch (std::exception& e) - { - std::cerr << "exception: " << e.what() << "\n"; - } - - return 0; -} diff --git a/asio/src/examples/cpp03/http/server/mime_types.cpp b/asio/src/examples/cpp03/http/server/mime_types.cpp deleted file mode 100644 index 745de030ab..0000000000 --- a/asio/src/examples/cpp03/http/server/mime_types.cpp +++ /dev/null @@ -1,46 +0,0 @@ -// -// mime_types.cpp -// ~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include "mime_types.hpp" - -namespace http { -namespace server { -namespace mime_types { - -struct mapping -{ - const char* extension; - const char* mime_type; -} mappings[] = -{ - { "gif", "image/gif" }, - { "htm", "text/html" }, - { "html", "text/html" }, - { "jpg", "image/jpeg" }, - { "png", "image/png" }, - { 0, 0 } // Marks end of list. -}; - -std::string extension_to_type(const std::string& extension) -{ - for (mapping* m = mappings; m->extension; ++m) - { - if (m->extension == extension) - { - return m->mime_type; - } - } - - return "text/plain"; -} - -} // namespace mime_types -} // namespace server -} // namespace http diff --git a/asio/src/examples/cpp03/http/server/mime_types.hpp b/asio/src/examples/cpp03/http/server/mime_types.hpp deleted file mode 100644 index 49f1defd44..0000000000 --- a/asio/src/examples/cpp03/http/server/mime_types.hpp +++ /dev/null @@ -1,27 +0,0 @@ -// -// mime_types.hpp -// ~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef HTTP_MIME_TYPES_HPP -#define HTTP_MIME_TYPES_HPP - -#include - -namespace http { -namespace server { -namespace mime_types { - -/// Convert a file extension into a MIME type. -std::string extension_to_type(const std::string& extension); - -} // namespace mime_types -} // namespace server -} // namespace http - -#endif // HTTP_MIME_TYPES_HPP diff --git a/asio/src/examples/cpp03/http/server/reply.cpp b/asio/src/examples/cpp03/http/server/reply.cpp deleted file mode 100644 index e57d43fdef..0000000000 --- a/asio/src/examples/cpp03/http/server/reply.cpp +++ /dev/null @@ -1,256 +0,0 @@ -// -// reply.cpp -// ~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include "reply.hpp" -#include -#include - -namespace http { -namespace server { - -namespace status_strings { - -const std::string ok = - "HTTP/1.0 200 OK\r\n"; -const std::string created = - "HTTP/1.0 201 Created\r\n"; -const std::string accepted = - "HTTP/1.0 202 Accepted\r\n"; -const std::string no_content = - "HTTP/1.0 204 No Content\r\n"; -const std::string multiple_choices = - "HTTP/1.0 300 Multiple Choices\r\n"; -const std::string moved_permanently = - "HTTP/1.0 301 Moved Permanently\r\n"; -const std::string moved_temporarily = - "HTTP/1.0 302 Moved Temporarily\r\n"; -const std::string not_modified = - "HTTP/1.0 304 Not Modified\r\n"; -const std::string bad_request = - "HTTP/1.0 400 Bad Request\r\n"; -const std::string unauthorized = - "HTTP/1.0 401 Unauthorized\r\n"; -const std::string forbidden = - "HTTP/1.0 403 Forbidden\r\n"; -const std::string not_found = - "HTTP/1.0 404 Not Found\r\n"; -const std::string internal_server_error = - "HTTP/1.0 500 Internal Server Error\r\n"; -const std::string not_implemented = - "HTTP/1.0 501 Not Implemented\r\n"; -const std::string bad_gateway = - "HTTP/1.0 502 Bad Gateway\r\n"; -const std::string service_unavailable = - "HTTP/1.0 503 Service Unavailable\r\n"; - -asio::const_buffer to_buffer(reply::status_type status) -{ - switch (status) - { - case reply::ok: - return asio::buffer(ok); - case reply::created: - return asio::buffer(created); - case reply::accepted: - return asio::buffer(accepted); - case reply::no_content: - return asio::buffer(no_content); - case reply::multiple_choices: - return asio::buffer(multiple_choices); - case reply::moved_permanently: - return asio::buffer(moved_permanently); - case reply::moved_temporarily: - return asio::buffer(moved_temporarily); - case reply::not_modified: - return asio::buffer(not_modified); - case reply::bad_request: - return asio::buffer(bad_request); - case reply::unauthorized: - return asio::buffer(unauthorized); - case reply::forbidden: - return asio::buffer(forbidden); - case reply::not_found: - return asio::buffer(not_found); - case reply::internal_server_error: - return asio::buffer(internal_server_error); - case reply::not_implemented: - return asio::buffer(not_implemented); - case reply::bad_gateway: - return asio::buffer(bad_gateway); - case reply::service_unavailable: - return asio::buffer(service_unavailable); - default: - return asio::buffer(internal_server_error); - } -} - -} // namespace status_strings - -namespace misc_strings { - -const char name_value_separator[] = { ':', ' ' }; -const char crlf[] = { '\r', '\n' }; - -} // namespace misc_strings - -std::vector reply::to_buffers() -{ - std::vector buffers; - buffers.push_back(status_strings::to_buffer(status)); - for (std::size_t i = 0; i < headers.size(); ++i) - { - header& h = headers[i]; - buffers.push_back(asio::buffer(h.name)); - buffers.push_back(asio::buffer(misc_strings::name_value_separator)); - buffers.push_back(asio::buffer(h.value)); - buffers.push_back(asio::buffer(misc_strings::crlf)); - } - buffers.push_back(asio::buffer(misc_strings::crlf)); - buffers.push_back(asio::buffer(content)); - return buffers; -} - -namespace stock_replies { - -const char ok[] = ""; -const char created[] = - "" - "Created" - "

201 Created

" - ""; -const char accepted[] = - "" - "Accepted" - "

202 Accepted

" - ""; -const char no_content[] = - "" - "No Content" - "

204 Content

" - ""; -const char multiple_choices[] = - "" - "Multiple Choices" - "

300 Multiple Choices

" - ""; -const char moved_permanently[] = - "" - "Moved Permanently" - "

301 Moved Permanently

" - ""; -const char moved_temporarily[] = - "" - "Moved Temporarily" - "

302 Moved Temporarily

" - ""; -const char not_modified[] = - "" - "Not Modified" - "

304 Not Modified

" - ""; -const char bad_request[] = - "" - "Bad Request" - "

400 Bad Request

" - ""; -const char unauthorized[] = - "" - "Unauthorized" - "

401 Unauthorized

" - ""; -const char forbidden[] = - "" - "Forbidden" - "

403 Forbidden

" - ""; -const char not_found[] = - "" - "Not Found" - "

404 Not Found

" - ""; -const char internal_server_error[] = - "" - "Internal Server Error" - "

500 Internal Server Error

" - ""; -const char not_implemented[] = - "" - "Not Implemented" - "

501 Not Implemented

" - ""; -const char bad_gateway[] = - "" - "Bad Gateway" - "

502 Bad Gateway

" - ""; -const char service_unavailable[] = - "" - "Service Unavailable" - "

503 Service Unavailable

" - ""; - -std::string to_string(reply::status_type status) -{ - switch (status) - { - case reply::ok: - return ok; - case reply::created: - return created; - case reply::accepted: - return accepted; - case reply::no_content: - return no_content; - case reply::multiple_choices: - return multiple_choices; - case reply::moved_permanently: - return moved_permanently; - case reply::moved_temporarily: - return moved_temporarily; - case reply::not_modified: - return not_modified; - case reply::bad_request: - return bad_request; - case reply::unauthorized: - return unauthorized; - case reply::forbidden: - return forbidden; - case reply::not_found: - return not_found; - case reply::internal_server_error: - return internal_server_error; - case reply::not_implemented: - return not_implemented; - case reply::bad_gateway: - return bad_gateway; - case reply::service_unavailable: - return service_unavailable; - default: - return internal_server_error; - } -} - -} // namespace stock_replies - -reply reply::stock_reply(reply::status_type status) -{ - reply rep; - rep.status = status; - rep.content = stock_replies::to_string(status); - rep.headers.resize(2); - rep.headers[0].name = "Content-Length"; - rep.headers[0].value = boost::lexical_cast(rep.content.size()); - rep.headers[1].name = "Content-Type"; - rep.headers[1].value = "text/html"; - return rep; -} - -} // namespace server -} // namespace http diff --git a/asio/src/examples/cpp03/http/server/reply.hpp b/asio/src/examples/cpp03/http/server/reply.hpp deleted file mode 100644 index 060a0fd014..0000000000 --- a/asio/src/examples/cpp03/http/server/reply.hpp +++ /dev/null @@ -1,64 +0,0 @@ -// -// reply.hpp -// ~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef HTTP_REPLY_HPP -#define HTTP_REPLY_HPP - -#include -#include -#include -#include "header.hpp" - -namespace http { -namespace server { - -/// A reply to be sent to a client. -struct reply -{ - /// The status of the reply. - enum status_type - { - ok = 200, - created = 201, - accepted = 202, - no_content = 204, - multiple_choices = 300, - moved_permanently = 301, - moved_temporarily = 302, - not_modified = 304, - bad_request = 400, - unauthorized = 401, - forbidden = 403, - not_found = 404, - internal_server_error = 500, - not_implemented = 501, - bad_gateway = 502, - service_unavailable = 503 - } status; - - /// The headers to be included in the reply. - std::vector
headers; - - /// The content to be sent in the reply. - std::string content; - - /// Convert the reply into a vector of buffers. The buffers do not own the - /// underlying memory blocks, therefore the reply object must remain valid and - /// not be changed until the write operation has completed. - std::vector to_buffers(); - - /// Get a stock reply. - static reply stock_reply(status_type status); -}; - -} // namespace server -} // namespace http - -#endif // HTTP_REPLY_HPP diff --git a/asio/src/examples/cpp03/http/server/server.cpp b/asio/src/examples/cpp03/http/server/server.cpp deleted file mode 100644 index 4c572f121e..0000000000 --- a/asio/src/examples/cpp03/http/server/server.cpp +++ /dev/null @@ -1,94 +0,0 @@ -// -// server.cpp -// ~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include "server.hpp" -#include -#include - -namespace http { -namespace server { - -server::server(const std::string& address, const std::string& port, - const std::string& doc_root) - : io_context_(), - signals_(io_context_), - acceptor_(io_context_), - connection_manager_(), - new_connection_(), - request_handler_(doc_root) -{ - // Register to handle the signals that indicate when the server should exit. - // It is safe to register for the same signal multiple times in a program, - // provided all registration for the specified signal is made through Asio. - signals_.add(SIGINT); - signals_.add(SIGTERM); -#if defined(SIGQUIT) - signals_.add(SIGQUIT); -#endif // defined(SIGQUIT) - signals_.async_wait(boost::bind(&server::handle_stop, this)); - - // Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR). - asio::ip::tcp::resolver resolver(io_context_); - asio::ip::tcp::endpoint endpoint = - *resolver.resolve(address, port).begin(); - acceptor_.open(endpoint.protocol()); - acceptor_.set_option(asio::ip::tcp::acceptor::reuse_address(true)); - acceptor_.bind(endpoint); - acceptor_.listen(); - - start_accept(); -} - -void server::run() -{ - // The io_context::run() call will block until all asynchronous operations - // have finished. While the server is running, there is always at least one - // asynchronous operation outstanding: the asynchronous accept call waiting - // for new incoming connections. - io_context_.run(); -} - -void server::start_accept() -{ - new_connection_.reset(new connection(io_context_, - connection_manager_, request_handler_)); - acceptor_.async_accept(new_connection_->socket(), - boost::bind(&server::handle_accept, this, - asio::placeholders::error)); -} - -void server::handle_accept(const asio::error_code& e) -{ - // Check whether the server was stopped by a signal before this completion - // handler had a chance to run. - if (!acceptor_.is_open()) - { - return; - } - - if (!e) - { - connection_manager_.start(new_connection_); - } - - start_accept(); -} - -void server::handle_stop() -{ - // The server is stopped by cancelling all outstanding asynchronous - // operations. Once all operations have finished the io_context::run() call - // will exit. - acceptor_.close(); - connection_manager_.stop_all(); -} - -} // namespace server -} // namespace http diff --git a/asio/src/examples/cpp03/http/server/server.hpp b/asio/src/examples/cpp03/http/server/server.hpp deleted file mode 100644 index fcd689c57c..0000000000 --- a/asio/src/examples/cpp03/http/server/server.hpp +++ /dev/null @@ -1,69 +0,0 @@ -// -// server.hpp -// ~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef HTTP_SERVER_HPP -#define HTTP_SERVER_HPP - -#include -#include -#include -#include "connection.hpp" -#include "connection_manager.hpp" -#include "request_handler.hpp" - -namespace http { -namespace server { - -/// The top-level class of the HTTP server. -class server - : private boost::noncopyable -{ -public: - /// Construct the server to listen on the specified TCP address and port, and - /// serve up files from the given directory. - explicit server(const std::string& address, const std::string& port, - const std::string& doc_root); - - /// Run the server's io_context loop. - void run(); - -private: - /// Initiate an asynchronous accept operation. - void start_accept(); - - /// Handle completion of an asynchronous accept operation. - void handle_accept(const asio::error_code& e); - - /// Handle a request to stop the server. - void handle_stop(); - - /// The io_context used to perform asynchronous operations. - asio::io_context io_context_; - - /// The signal_set is used to register for process termination notifications. - asio::signal_set signals_; - - /// Acceptor used to listen for incoming connections. - asio::ip::tcp::acceptor acceptor_; - - /// The connection manager which owns all live connections. - connection_manager connection_manager_; - - /// The next connection to be accepted. - connection_ptr new_connection_; - - /// The handler for all incoming requests. - request_handler request_handler_; -}; - -} // namespace server -} // namespace http - -#endif // HTTP_SERVER_HPP diff --git a/asio/src/examples/cpp03/http/server2/.gitignore b/asio/src/examples/cpp03/http/server2/.gitignore deleted file mode 100644 index 0882fa6ced..0000000000 --- a/asio/src/examples/cpp03/http/server2/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -.deps -.dirstamp -*.o -*.obj -*.exe -*_server -*_client -*.ilk -*.manifest -*.pdb -*.tds diff --git a/asio/src/examples/cpp03/http/server2/connection.cpp b/asio/src/examples/cpp03/http/server2/connection.cpp deleted file mode 100644 index f6a5e0396c..0000000000 --- a/asio/src/examples/cpp03/http/server2/connection.cpp +++ /dev/null @@ -1,93 +0,0 @@ -// -// connection.cpp -// ~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include "connection.hpp" -#include -#include -#include "request_handler.hpp" - -namespace http { -namespace server2 { - -connection::connection(asio::io_context& io_context, - request_handler& handler) - : socket_(io_context), - request_handler_(handler) -{ -} - -asio::ip::tcp::socket& connection::socket() -{ - return socket_; -} - -void connection::start() -{ - socket_.async_read_some(asio::buffer(buffer_), - boost::bind(&connection::handle_read, shared_from_this(), - asio::placeholders::error, - asio::placeholders::bytes_transferred)); -} - -void connection::handle_read(const asio::error_code& e, - std::size_t bytes_transferred) -{ - if (!e) - { - boost::tribool result; - boost::tie(result, boost::tuples::ignore) = request_parser_.parse( - request_, buffer_.data(), buffer_.data() + bytes_transferred); - - if (result) - { - request_handler_.handle_request(request_, reply_); - asio::async_write(socket_, reply_.to_buffers(), - boost::bind(&connection::handle_write, shared_from_this(), - asio::placeholders::error)); - } - else if (!result) - { - reply_ = reply::stock_reply(reply::bad_request); - asio::async_write(socket_, reply_.to_buffers(), - boost::bind(&connection::handle_write, shared_from_this(), - asio::placeholders::error)); - } - else - { - socket_.async_read_some(asio::buffer(buffer_), - boost::bind(&connection::handle_read, shared_from_this(), - asio::placeholders::error, - asio::placeholders::bytes_transferred)); - } - } - - // If an error occurs then no new asynchronous operations are started. This - // means that all shared_ptr references to the connection object will - // disappear and the object will be destroyed automatically after this - // handler returns. The connection class's destructor closes the socket. -} - -void connection::handle_write(const asio::error_code& e) -{ - if (!e) - { - // Initiate graceful connection closure. - asio::error_code ignored_ec; - socket_.shutdown(asio::ip::tcp::socket::shutdown_both, ignored_ec); - } - - // No new asynchronous operations are started. This means that all shared_ptr - // references to the connection object will disappear and the object will be - // destroyed automatically after this handler returns. The connection class's - // destructor closes the socket. -} - -} // namespace server2 -} // namespace http diff --git a/asio/src/examples/cpp03/http/server3/.gitignore b/asio/src/examples/cpp03/http/server3/.gitignore deleted file mode 100644 index 0882fa6ced..0000000000 --- a/asio/src/examples/cpp03/http/server3/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -.deps -.dirstamp -*.o -*.obj -*.exe -*_server -*_client -*.ilk -*.manifest -*.pdb -*.tds diff --git a/asio/src/examples/cpp03/http/server3/connection.cpp b/asio/src/examples/cpp03/http/server3/connection.cpp deleted file mode 100644 index e8fced9dc3..0000000000 --- a/asio/src/examples/cpp03/http/server3/connection.cpp +++ /dev/null @@ -1,94 +0,0 @@ -// -// connection.cpp -// ~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include "connection.hpp" -#include -#include -#include "request_handler.hpp" - -namespace http { -namespace server3 { - -connection::connection(asio::io_context& io_context, - request_handler& handler) - : strand_(asio::make_strand(io_context)), - socket_(strand_), - request_handler_(handler) -{ -} - -asio::ip::tcp::socket& connection::socket() -{ - return socket_; -} - -void connection::start() -{ - socket_.async_read_some(asio::buffer(buffer_), - boost::bind(&connection::handle_read, shared_from_this(), - asio::placeholders::error, - asio::placeholders::bytes_transferred)); -} - -void connection::handle_read(const asio::error_code& e, - std::size_t bytes_transferred) -{ - if (!e) - { - boost::tribool result; - boost::tie(result, boost::tuples::ignore) = request_parser_.parse( - request_, buffer_.data(), buffer_.data() + bytes_transferred); - - if (result) - { - request_handler_.handle_request(request_, reply_); - asio::async_write(socket_, reply_.to_buffers(), - boost::bind(&connection::handle_write, shared_from_this(), - asio::placeholders::error)); - } - else if (!result) - { - reply_ = reply::stock_reply(reply::bad_request); - asio::async_write(socket_, reply_.to_buffers(), - boost::bind(&connection::handle_write, shared_from_this(), - asio::placeholders::error)); - } - else - { - socket_.async_read_some(asio::buffer(buffer_), - boost::bind(&connection::handle_read, shared_from_this(), - asio::placeholders::error, - asio::placeholders::bytes_transferred)); - } - } - - // If an error occurs then no new asynchronous operations are started. This - // means that all shared_ptr references to the connection object will - // disappear and the object will be destroyed automatically after this - // handler returns. The connection class's destructor closes the socket. -} - -void connection::handle_write(const asio::error_code& e) -{ - if (!e) - { - // Initiate graceful connection closure. - asio::error_code ignored_ec; - socket_.shutdown(asio::ip::tcp::socket::shutdown_both, ignored_ec); - } - - // No new asynchronous operations are started. This means that all shared_ptr - // references to the connection object will disappear and the object will be - // destroyed automatically after this handler returns. The connection class's - // destructor closes the socket. -} - -} // namespace server3 -} // namespace http diff --git a/asio/src/examples/cpp03/http/server4/.gitignore b/asio/src/examples/cpp03/http/server4/.gitignore deleted file mode 100644 index 0882fa6ced..0000000000 --- a/asio/src/examples/cpp03/http/server4/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -.deps -.dirstamp -*.o -*.obj -*.exe -*_server -*_client -*.ilk -*.manifest -*.pdb -*.tds diff --git a/asio/src/examples/cpp03/http/server4/request.hpp b/asio/src/examples/cpp03/http/server4/request.hpp deleted file mode 100644 index 8e00525d94..0000000000 --- a/asio/src/examples/cpp03/http/server4/request.hpp +++ /dev/null @@ -1,46 +0,0 @@ -// -// request.hpp -// ~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef HTTP_SERVER4_REQUEST_HPP -#define HTTP_SERVER4_REQUEST_HPP - -#include -#include -#include "header.hpp" - -namespace http { -namespace server4 { - -/// A request received from a client. -struct request -{ - /// The request method, e.g. "GET", "POST". - std::string method; - - /// The requested URI, such as a path to a file. - std::string uri; - - /// Major version number, usually 1. - int http_version_major; - - /// Minor version number, usually 0 or 1. - int http_version_minor; - - /// The headers included with the request. - std::vector
headers; - - /// The optional content sent with the request. - std::string content; -}; - -} // namespace server4 -} // namespace http - -#endif // HTTP_SERVER4_REQUEST_HPP diff --git a/asio/src/examples/cpp03/http/server4/request_parser.cpp b/asio/src/examples/cpp03/http/server4/request_parser.cpp deleted file mode 100644 index 37ac005e24..0000000000 --- a/asio/src/examples/cpp03/http/server4/request_parser.cpp +++ /dev/null @@ -1,226 +0,0 @@ -// -// request_parser.cpp -// ~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include "request_parser.hpp" -#include -#include -#include -#include "request.hpp" - -namespace http { -namespace server4 { - -// Enable the pseudo-keywords reenter, yield and fork. -#include - -std::string request_parser::content_length_name_ = "Content-Length"; - -boost::tribool request_parser::consume(request& req, char c) -{ - reenter (this) - { - req.method.clear(); - req.uri.clear(); - req.http_version_major = 0; - req.http_version_minor = 0; - req.headers.clear(); - req.content.clear(); - content_length_ = 0; - - // Request method. - while (is_char(c) && !is_ctl(c) && !is_tspecial(c) && c != ' ') - { - req.method.push_back(c); - yield return boost::indeterminate; - } - if (req.method.empty()) - return false; - - // Space. - if (c != ' ') return false; - yield return boost::indeterminate; - - // URI. - while (!is_ctl(c) && c != ' ') - { - req.uri.push_back(c); - yield return boost::indeterminate; - } - if (req.uri.empty()) return false; - - // Space. - if (c != ' ') return false; - yield return boost::indeterminate; - - // HTTP protocol identifier. - if (c != 'H') return false; - yield return boost::indeterminate; - if (c != 'T') return false; - yield return boost::indeterminate; - if (c != 'T') return false; - yield return boost::indeterminate; - if (c != 'P') return false; - yield return boost::indeterminate; - - // Slash. - if (c != '/') return false; - yield return boost::indeterminate; - - // Major version number. - if (!is_digit(c)) return false; - while (is_digit(c)) - { - req.http_version_major = req.http_version_major * 10 + c - '0'; - yield return boost::indeterminate; - } - - // Dot. - if (c != '.') return false; - yield return boost::indeterminate; - - // Minor version number. - if (!is_digit(c)) return false; - while (is_digit(c)) - { - req.http_version_minor = req.http_version_minor * 10 + c - '0'; - yield return boost::indeterminate; - } - - // CRLF. - if (c != '\r') return false; - yield return boost::indeterminate; - if (c != '\n') return false; - yield return boost::indeterminate; - - // Headers. - while ((is_char(c) && !is_ctl(c) && !is_tspecial(c) && c != '\r') - || (c == ' ' || c == '\t')) - { - if (c == ' ' || c == '\t') - { - // Leading whitespace. Must be continuation of previous header's value. - if (req.headers.empty()) return false; - while (c == ' ' || c == '\t') - yield return boost::indeterminate; - } - else - { - // Start the next header. - req.headers.push_back(header()); - - // Header name. - while (is_char(c) && !is_ctl(c) && !is_tspecial(c) && c != ':') - { - req.headers.back().name.push_back(c); - yield return boost::indeterminate; - } - - // Colon and space separates the header name from the header value. - if (c != ':') return false; - yield return boost::indeterminate; - if (c != ' ') return false; - yield return boost::indeterminate; - } - - // Header value. - while (is_char(c) && !is_ctl(c) && c != '\r') - { - req.headers.back().value.push_back(c); - yield return boost::indeterminate; - } - - // CRLF. - if (c != '\r') return false; - yield return boost::indeterminate; - if (c != '\n') return false; - yield return boost::indeterminate; - } - - // CRLF. - if (c != '\r') return false; - yield return boost::indeterminate; - if (c != '\n') return false; - - // Check for optional Content-Length header. - for (std::size_t i = 0; i < req.headers.size(); ++i) - { - if (headers_equal(req.headers[i].name, content_length_name_)) - { - try - { - content_length_ = - boost::lexical_cast(req.headers[i].value); - } - catch (boost::bad_lexical_cast&) - { - return false; - } - } - } - - // Content. - while (req.content.size() < content_length_) - { - yield return boost::indeterminate; - req.content.push_back(c); - } - } - - return true; -} - -// Disable the pseudo-keywords reenter, yield and fork. -#include - -bool request_parser::is_char(int c) -{ - return c >= 0 && c <= 127; -} - -bool request_parser::is_ctl(int c) -{ - return (c >= 0 && c <= 31) || (c == 127); -} - -bool request_parser::is_tspecial(int c) -{ - switch (c) - { - case '(': case ')': case '<': case '>': case '@': - case ',': case ';': case ':': case '\\': case '"': - case '/': case '[': case ']': case '?': case '=': - case '{': case '}': case ' ': case '\t': - return true; - default: - return false; - } -} - -bool request_parser::is_digit(int c) -{ - return c >= '0' && c <= '9'; -} - -bool request_parser::tolower_compare(char a, char b) -{ - return std::tolower(a) == std::tolower(b); -} - -bool request_parser::headers_equal(const std::string& a, const std::string& b) -{ - if (a.length() != b.length()) - return false; - - return std::equal(a.begin(), a.end(), b.begin(), - &request_parser::tolower_compare); -} - -} // namespace server4 -} // namespace http diff --git a/asio/src/examples/cpp03/http/server4/request_parser.hpp b/asio/src/examples/cpp03/http/server4/request_parser.hpp deleted file mode 100644 index 7c8b4bca81..0000000000 --- a/asio/src/examples/cpp03/http/server4/request_parser.hpp +++ /dev/null @@ -1,78 +0,0 @@ -// -// request_parser.hpp -// ~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef HTTP_SERVER4_REQUEST_PARSER_HPP -#define HTTP_SERVER4_REQUEST_PARSER_HPP - -#include -#include -#include -#include - -namespace http { -namespace server4 { - -struct request; - -/// Parser for incoming requests. -class request_parser : asio::coroutine -{ -public: - /// Parse some data. The tribool return value is true when a complete request - /// has been parsed, false if the data is invalid, indeterminate when more - /// data is required. The InputIterator return value indicates how much of the - /// input has been consumed. - template - boost::tuple parse(request& req, - InputIterator begin, InputIterator end) - { - while (begin != end) - { - boost::tribool result = consume(req, *begin++); - if (result || !result) - return boost::make_tuple(result, begin); - } - boost::tribool result = boost::indeterminate; - return boost::make_tuple(result, begin); - } - -private: - /// The name of the content length header. - static std::string content_length_name_; - - /// Content length as decoded from headers. Defaults to 0. - std::size_t content_length_; - - /// Handle the next character of input. - boost::tribool consume(request& req, char input); - - /// Check if a byte is an HTTP character. - static bool is_char(int c); - - /// Check if a byte is an HTTP control character. - static bool is_ctl(int c); - - /// Check if a byte is defined as an HTTP tspecial character. - static bool is_tspecial(int c); - - /// Check if a byte is a digit. - static bool is_digit(int c); - - /// Check if two characters are equal, without regard to case. - static bool tolower_compare(char a, char b); - - /// Check whether the two request header names match. - bool headers_equal(const std::string& a, const std::string& b); -}; - -} // namespace server4 -} // namespace http - -#endif // HTTP_SERVER4_REQUEST_PARSER_HPP diff --git a/asio/src/examples/cpp03/invocation/.gitignore b/asio/src/examples/cpp03/invocation/.gitignore deleted file mode 100644 index e5876b7811..0000000000 --- a/asio/src/examples/cpp03/invocation/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -.deps -.dirstamp -*.o -*.obj -*.exe -prioritised_handlers -*.ilk -*.manifest -*.pdb -*.tds diff --git a/asio/src/examples/cpp03/invocation/prioritised_handlers.cpp b/asio/src/examples/cpp03/invocation/prioritised_handlers.cpp deleted file mode 100644 index 5caf587e06..0000000000 --- a/asio/src/examples/cpp03/invocation/prioritised_handlers.cpp +++ /dev/null @@ -1,171 +0,0 @@ -// -// prioritised_handlers.cpp -// ~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include "asio.hpp" -#include -#include -#include - -using asio::ip::tcp; - -class handler_priority_queue : public asio::execution_context -{ -public: - void add(int priority, boost::function function) - { - handlers_.push(queued_handler(priority, function)); - } - - void execute_all() - { - while (!handlers_.empty()) - { - queued_handler handler = handlers_.top(); - handler.execute(); - handlers_.pop(); - } - } - - class executor - { - public: - executor(handler_priority_queue& q, int p) - : context_(q), priority_(p) - { - } - - handler_priority_queue& context() const - { - return context_; - } - - template - void dispatch(const Function& f, const Allocator&) const - { - context_.add(priority_, f); - } - - template - void post(const Function& f, const Allocator&) const - { - context_.add(priority_, f); - } - - template - void defer(const Function& f, const Allocator&) const - { - context_.add(priority_, f); - } - - void on_work_started() const {} - void on_work_finished() const {} - - bool operator==(const executor& other) const - { - return &context_ == &other.context_ && priority_ == other.priority_; - } - - bool operator!=(const executor& other) const - { - return !operator==(other); - } - - private: - handler_priority_queue& context_; - int priority_; - }; - - template - asio::executor_binder - wrap(int priority, Handler handler) - { - return asio::bind_executor(executor(*this, priority), handler); - } - -private: - class queued_handler - { - public: - queued_handler(int p, boost::function f) - : priority_(p), function_(f) - { - } - - void execute() - { - function_(); - } - - friend bool operator<(const queued_handler& a, - const queued_handler& b) - { - return a.priority_ < b.priority_; - } - - private: - int priority_; - boost::function function_; - }; - - std::priority_queue handlers_; -}; - -//---------------------------------------------------------------------- - -void high_priority_handler(const asio::error_code& /*ec*/) -{ - std::cout << "High priority handler\n"; -} - -void middle_priority_handler(const asio::error_code& /*ec*/) -{ - std::cout << "Middle priority handler\n"; -} - -void low_priority_handler() -{ - std::cout << "Low priority handler\n"; -} - -int main() -{ - asio::io_context io_context; - - handler_priority_queue pri_queue; - - // Post a completion handler to be run immediately. - asio::post(io_context, pri_queue.wrap(0, low_priority_handler)); - - // Start an asynchronous accept that will complete immediately. - tcp::endpoint endpoint(asio::ip::address_v4::loopback(), 0); - tcp::acceptor acceptor(io_context, endpoint); - tcp::socket server_socket(io_context); - acceptor.async_accept(server_socket, - pri_queue.wrap(100, high_priority_handler)); - tcp::socket client_socket(io_context); - client_socket.connect(acceptor.local_endpoint()); - - // Set a deadline timer to expire immediately. - asio::steady_timer timer(io_context); - timer.expires_at(asio::steady_timer::time_point::min()); - timer.async_wait(pri_queue.wrap(42, middle_priority_handler)); - - while (io_context.run_one()) - { - // The custom invocation hook adds the handlers to the priority queue - // rather than executing them from within the poll_one() call. - while (io_context.poll_one()) - ; - - pri_queue.execute_all(); - } - - return 0; -} diff --git a/asio/src/examples/cpp03/iostreams/.gitignore b/asio/src/examples/cpp03/iostreams/.gitignore deleted file mode 100644 index bc2b4f8f7f..0000000000 --- a/asio/src/examples/cpp03/iostreams/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -.deps -.dirstamp -*.o -*.obj -*.exe -*_client -*_server -*.ilk -*.manifest -*.pdb -*.tds diff --git a/asio/src/examples/cpp03/iostreams/http_client.cpp b/asio/src/examples/cpp03/iostreams/http_client.cpp deleted file mode 100644 index 3e6e24e830..0000000000 --- a/asio/src/examples/cpp03/iostreams/http_client.cpp +++ /dev/null @@ -1,91 +0,0 @@ -// -// http_client.cpp -// ~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include -#include -#include -#include -#include - -using asio::ip::tcp; - -int main(int argc, char* argv[]) -{ - try - { - if (argc != 3) - { - std::cout << "Usage: http_client \n"; - std::cout << "Example:\n"; - std::cout << " http_client www.boost.org /LICENSE_1_0.txt\n"; - return 1; - } - - asio::ip::tcp::iostream s; - - // The entire sequence of I/O operations must complete within 60 seconds. - // If an expiry occurs, the socket is automatically closed and the stream - // becomes bad. - s.expires_after(asio::chrono::seconds(60)); - - // Establish a connection to the server. - s.connect(argv[1], "http"); - if (!s) - { - std::cout << "Unable to connect: " << s.error().message() << "\n"; - return 1; - } - - // Send the request. We specify the "Connection: close" header so that the - // server will close the socket after transmitting the response. This will - // allow us to treat all data up until the EOF as the content. - s << "GET " << argv[2] << " HTTP/1.0\r\n"; - s << "Host: " << argv[1] << "\r\n"; - s << "Accept: */*\r\n"; - s << "Connection: close\r\n\r\n"; - - // By default, the stream is tied with itself. This means that the stream - // automatically flush the buffered output before attempting a read. It is - // not necessary not explicitly flush the stream at this point. - - // Check that response is OK. - std::string http_version; - s >> http_version; - unsigned int status_code; - s >> status_code; - std::string status_message; - std::getline(s, status_message); - if (!s || http_version.substr(0, 5) != "HTTP/") - { - std::cout << "Invalid response\n"; - return 1; - } - if (status_code != 200) - { - std::cout << "Response returned with status code " << status_code << "\n"; - return 1; - } - - // Process the response headers, which are terminated by a blank line. - std::string header; - while (std::getline(s, header) && header != "\r") - std::cout << header << "\n"; - std::cout << "\n"; - - // Write the remaining data to output. - std::cout << s.rdbuf(); - } - catch (std::exception& e) - { - std::cout << "Exception: " << e.what() << "\n"; - } - - return 0; -} diff --git a/asio/src/examples/cpp03/local/.gitignore b/asio/src/examples/cpp03/local/.gitignore deleted file mode 100644 index 688277b48d..0000000000 --- a/asio/src/examples/cpp03/local/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -.deps -.dirstamp -*.o -*.obj -*.exe -connect_pair -stream_server -stream_client -iostream_client -*.ilk -*.manifest -*.pdb -*.tds diff --git a/asio/src/examples/cpp03/local/connect_pair.cpp b/asio/src/examples/cpp03/local/connect_pair.cpp deleted file mode 100644 index 53cc0d5248..0000000000 --- a/asio/src/examples/cpp03/local/connect_pair.cpp +++ /dev/null @@ -1,141 +0,0 @@ -// -// connect_pair.cpp -// ~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include -#include -#include -#include -#include -#include - -#if defined(ASIO_HAS_LOCAL_SOCKETS) - -using asio::local::stream_protocol; - -class uppercase_filter -{ -public: - uppercase_filter(asio::io_context& io_context) - : socket_(io_context) - { - } - - stream_protocol::socket& socket() - { - return socket_; - } - - void start() - { - // Wait for request. - socket_.async_read_some(asio::buffer(data_), - boost::bind(&uppercase_filter::handle_read, - this, asio::placeholders::error, - asio::placeholders::bytes_transferred)); - } - -private: - void handle_read(const asio::error_code& ec, std::size_t size) - { - if (!ec) - { - // Compute result. - for (std::size_t i = 0; i < size; ++i) - data_[i] = std::toupper(data_[i]); - - // Send result. - asio::async_write(socket_, asio::buffer(data_, size), - boost::bind(&uppercase_filter::handle_write, - this, asio::placeholders::error)); - } - else - { - throw asio::system_error(ec); - } - } - - void handle_write(const asio::error_code& ec) - { - if (!ec) - { - // Wait for request. - socket_.async_read_some(asio::buffer(data_), - boost::bind(&uppercase_filter::handle_read, - this, asio::placeholders::error, - asio::placeholders::bytes_transferred)); - } - else - { - throw asio::system_error(ec); - } - } - - stream_protocol::socket socket_; - boost::array data_; -}; - -void run(asio::io_context* io_context) -{ - try - { - io_context->run(); - } - catch (std::exception& e) - { - std::cerr << "Exception in thread: " << e.what() << "\n"; - std::exit(1); - } -} - -int main() -{ - try - { - asio::io_context io_context; - - // Create filter and establish a connection to it. - uppercase_filter filter(io_context); - stream_protocol::socket socket(io_context); - asio::local::connect_pair(socket, filter.socket()); - filter.start(); - - // The io_context runs in a background thread to perform filtering. - asio::thread thread(boost::bind(run, &io_context)); - - for (;;) - { - // Collect request from user. - std::cout << "Enter a string: "; - std::string request; - std::getline(std::cin, request); - - // Send request to filter. - asio::write(socket, asio::buffer(request)); - - // Wait for reply from filter. - std::vector reply(request.size()); - asio::read(socket, asio::buffer(reply)); - - // Show reply to user. - std::cout << "Result: "; - std::cout.write(&reply[0], request.size()); - std::cout << std::endl; - } - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - std::exit(1); - } -} - -#else // defined(ASIO_HAS_LOCAL_SOCKETS) -# error Local sockets not available on this platform. -#endif // defined(ASIO_HAS_LOCAL_SOCKETS) diff --git a/asio/src/examples/cpp03/local/iostream_client.cpp b/asio/src/examples/cpp03/local/iostream_client.cpp deleted file mode 100644 index 0ebaa23d8c..0000000000 --- a/asio/src/examples/cpp03/local/iostream_client.cpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// stream_client.cpp -// ~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include -#include -#include "asio.hpp" - -#if defined(ASIO_HAS_LOCAL_SOCKETS) - -using asio::local::stream_protocol; - -enum { max_length = 1024 }; - -int main(int argc, char* argv[]) -{ - try - { - if (argc != 2) - { - std::cerr << "Usage: iostream_client \n"; - return 1; - } - - stream_protocol::endpoint ep(argv[1]); - stream_protocol::iostream s(ep); - if (!s) - { - std::cerr << "Unable to connect: " << s.error().message() << std::endl; - return 1; - } - - using namespace std; // For strlen. - std::cout << "Enter message: "; - char request[max_length]; - std::cin.getline(request, max_length); - size_t length = strlen(request); - s << request; - - char reply[max_length]; - s.read(reply, length); - std::cout << "Reply is: "; - std::cout.write(reply, length); - std::cout << "\n"; - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - } - - return 0; -} - -#else // defined(ASIO_HAS_LOCAL_SOCKETS) -# error Local sockets not available on this platform. -#endif // defined(ASIO_HAS_LOCAL_SOCKETS) diff --git a/asio/src/examples/cpp03/local/stream_client.cpp b/asio/src/examples/cpp03/local/stream_client.cpp deleted file mode 100644 index 80674a4798..0000000000 --- a/asio/src/examples/cpp03/local/stream_client.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// -// stream_client.cpp -// ~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include -#include -#include -#include "asio.hpp" - -#if defined(ASIO_HAS_LOCAL_SOCKETS) - -using asio::local::stream_protocol; - -enum { max_length = 1024 }; - -int main(int argc, char* argv[]) -{ - try - { - if (argc != 2) - { - std::cerr << "Usage: stream_client \n"; - return 1; - } - - asio::io_context io_context; - - stream_protocol::socket s(io_context); - s.connect(stream_protocol::endpoint(argv[1])); - - using namespace std; // For strlen. - std::cout << "Enter message: "; - char request[max_length]; - std::cin.getline(request, max_length); - size_t request_length = strlen(request); - asio::write(s, asio::buffer(request, request_length)); - - char reply[max_length]; - size_t reply_length = asio::read(s, - asio::buffer(reply, request_length)); - std::cout << "Reply is: "; - std::cout.write(reply, reply_length); - std::cout << "\n"; - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - } - - return 0; -} - -#else // defined(ASIO_HAS_LOCAL_SOCKETS) -# error Local sockets not available on this platform. -#endif // defined(ASIO_HAS_LOCAL_SOCKETS) diff --git a/asio/src/examples/cpp03/local/stream_server.cpp b/asio/src/examples/cpp03/local/stream_server.cpp deleted file mode 100644 index f54d5a054d..0000000000 --- a/asio/src/examples/cpp03/local/stream_server.cpp +++ /dev/null @@ -1,141 +0,0 @@ -// -// stream_server.cpp -// ~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include -#include -#include -#include -#include -#include -#include "asio.hpp" - -#if defined(ASIO_HAS_LOCAL_SOCKETS) - -using asio::local::stream_protocol; - -class session - : public boost::enable_shared_from_this -{ -public: - session(asio::io_context& io_context) - : socket_(io_context) - { - } - - stream_protocol::socket& socket() - { - return socket_; - } - - void start() - { - socket_.async_read_some(asio::buffer(data_), - boost::bind(&session::handle_read, - shared_from_this(), - asio::placeholders::error, - asio::placeholders::bytes_transferred)); - } - - void handle_read(const asio::error_code& error, - size_t bytes_transferred) - { - if (!error) - { - asio::async_write(socket_, - asio::buffer(data_, bytes_transferred), - boost::bind(&session::handle_write, - shared_from_this(), - asio::placeholders::error)); - } - } - - void handle_write(const asio::error_code& error) - { - if (!error) - { - socket_.async_read_some(asio::buffer(data_), - boost::bind(&session::handle_read, - shared_from_this(), - asio::placeholders::error, - asio::placeholders::bytes_transferred)); - } - } - -private: - // The socket used to communicate with the client. - stream_protocol::socket socket_; - - // Buffer used to store data received from the client. - boost::array data_; -}; - -typedef boost::shared_ptr session_ptr; - -class server -{ -public: - server(asio::io_context& io_context, const std::string& file) - : io_context_(io_context), - acceptor_(io_context, stream_protocol::endpoint(file)) - { - session_ptr new_session(new session(io_context_)); - acceptor_.async_accept(new_session->socket(), - boost::bind(&server::handle_accept, this, new_session, - asio::placeholders::error)); - } - - void handle_accept(session_ptr new_session, - const asio::error_code& error) - { - if (!error) - { - new_session->start(); - } - - new_session.reset(new session(io_context_)); - acceptor_.async_accept(new_session->socket(), - boost::bind(&server::handle_accept, this, new_session, - asio::placeholders::error)); - } - -private: - asio::io_context& io_context_; - stream_protocol::acceptor acceptor_; -}; - -int main(int argc, char* argv[]) -{ - try - { - if (argc != 2) - { - std::cerr << "Usage: stream_server \n"; - std::cerr << "*** WARNING: existing file is removed ***\n"; - return 1; - } - - asio::io_context io_context; - - std::remove(argv[1]); - server s(io_context, argv[1]); - - io_context.run(); - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - } - - return 0; -} - -#else // defined(ASIO_HAS_LOCAL_SOCKETS) -# error Local sockets not available on this platform. -#endif // defined(ASIO_HAS_LOCAL_SOCKETS) diff --git a/asio/src/examples/cpp03/multicast/.gitignore b/asio/src/examples/cpp03/multicast/.gitignore deleted file mode 100644 index 0c30ebdd7d..0000000000 --- a/asio/src/examples/cpp03/multicast/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -.deps -.dirstamp -receiver -sender -*.o -*.obj -*.exe -*.ilk -*.manifest -*.pdb -*.tds diff --git a/asio/src/examples/cpp03/multicast/receiver.cpp b/asio/src/examples/cpp03/multicast/receiver.cpp deleted file mode 100644 index b06bdd7789..0000000000 --- a/asio/src/examples/cpp03/multicast/receiver.cpp +++ /dev/null @@ -1,93 +0,0 @@ -// -// receiver.cpp -// ~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include -#include -#include "asio.hpp" -#include "boost/bind/bind.hpp" - -const short multicast_port = 30001; - -class receiver -{ -public: - receiver(asio::io_context& io_context, - const asio::ip::address& listen_address, - const asio::ip::address& multicast_address) - : socket_(io_context) - { - // Create the socket so that multiple may be bound to the same address. - asio::ip::udp::endpoint listen_endpoint( - listen_address, multicast_port); - socket_.open(listen_endpoint.protocol()); - socket_.set_option(asio::ip::udp::socket::reuse_address(true)); - socket_.bind(listen_endpoint); - - // Join the multicast group. - socket_.set_option( - asio::ip::multicast::join_group(multicast_address)); - - socket_.async_receive_from( - asio::buffer(data_, max_length), sender_endpoint_, - boost::bind(&receiver::handle_receive_from, this, - asio::placeholders::error, - asio::placeholders::bytes_transferred)); - } - - void handle_receive_from(const asio::error_code& error, - size_t bytes_recvd) - { - if (!error) - { - std::cout.write(data_, bytes_recvd); - std::cout << std::endl; - - socket_.async_receive_from( - asio::buffer(data_, max_length), sender_endpoint_, - boost::bind(&receiver::handle_receive_from, this, - asio::placeholders::error, - asio::placeholders::bytes_transferred)); - } - } - -private: - asio::ip::udp::socket socket_; - asio::ip::udp::endpoint sender_endpoint_; - enum { max_length = 1024 }; - char data_[max_length]; -}; - -int main(int argc, char* argv[]) -{ - try - { - if (argc != 3) - { - std::cerr << "Usage: receiver \n"; - std::cerr << " For IPv4, try:\n"; - std::cerr << " receiver 0.0.0.0 239.255.0.1\n"; - std::cerr << " For IPv6, try:\n"; - std::cerr << " receiver 0::0 ff31::8000:1234\n"; - return 1; - } - - asio::io_context io_context; - receiver r(io_context, - asio::ip::make_address(argv[1]), - asio::ip::make_address(argv[2])); - io_context.run(); - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - } - - return 0; -} diff --git a/asio/src/examples/cpp03/multicast/sender.cpp b/asio/src/examples/cpp03/multicast/sender.cpp deleted file mode 100644 index 3006b0b22d..0000000000 --- a/asio/src/examples/cpp03/multicast/sender.cpp +++ /dev/null @@ -1,98 +0,0 @@ -// -// sender.cpp -// ~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include -#include -#include -#include "asio.hpp" -#include "boost/bind/bind.hpp" - -const short multicast_port = 30001; -const int max_message_count = 10; - -class sender -{ -public: - sender(asio::io_context& io_context, - const asio::ip::address& multicast_address) - : endpoint_(multicast_address, multicast_port), - socket_(io_context, endpoint_.protocol()), - timer_(io_context), - message_count_(0) - { - std::ostringstream os; - os << "Message " << message_count_++; - message_ = os.str(); - - socket_.async_send_to( - asio::buffer(message_), endpoint_, - boost::bind(&sender::handle_send_to, this, - asio::placeholders::error)); - } - - void handle_send_to(const asio::error_code& error) - { - if (!error && message_count_ < max_message_count) - { - timer_.expires_after(asio::chrono::seconds(1)); - timer_.async_wait( - boost::bind(&sender::handle_timeout, this, - asio::placeholders::error)); - } - } - - void handle_timeout(const asio::error_code& error) - { - if (!error) - { - std::ostringstream os; - os << "Message " << message_count_++; - message_ = os.str(); - - socket_.async_send_to( - asio::buffer(message_), endpoint_, - boost::bind(&sender::handle_send_to, this, - asio::placeholders::error)); - } - } - -private: - asio::ip::udp::endpoint endpoint_; - asio::ip::udp::socket socket_; - asio::steady_timer timer_; - int message_count_; - std::string message_; -}; - -int main(int argc, char* argv[]) -{ - try - { - if (argc != 2) - { - std::cerr << "Usage: sender \n"; - std::cerr << " For IPv4, try:\n"; - std::cerr << " sender 239.255.0.1\n"; - std::cerr << " For IPv6, try:\n"; - std::cerr << " sender ff31::8000:1234\n"; - return 1; - } - - asio::io_context io_context; - sender s(io_context, asio::ip::make_address(argv[1])); - io_context.run(); - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - } - - return 0; -} diff --git a/asio/src/examples/cpp03/nonblocking/.gitignore b/asio/src/examples/cpp03/nonblocking/.gitignore deleted file mode 100644 index 760e0dcebb..0000000000 --- a/asio/src/examples/cpp03/nonblocking/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -.deps -.dirstamp -*.o -*.obj -*.exe -third_party_lib -*.ilk -*.manifest -*.pdb -*.tds diff --git a/asio/src/examples/cpp03/nonblocking/third_party_lib.cpp b/asio/src/examples/cpp03/nonblocking/third_party_lib.cpp deleted file mode 100644 index 1766051a32..0000000000 --- a/asio/src/examples/cpp03/nonblocking/third_party_lib.cpp +++ /dev/null @@ -1,240 +0,0 @@ -// -// third_party_lib.cpp -// ~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include -#include -#include -#include -#include -#include - -using asio::ip::tcp; - -namespace third_party_lib { - -// Simulation of a third party library that wants to perform read and write -// operations directly on a socket. It needs to be polled to determine whether -// it requires a read or write operation, and notified when the socket is ready -// for reading or writing. -class session -{ -public: - session(tcp::socket& socket) - : socket_(socket), - state_(reading) - { - } - - // Returns true if the third party library wants to be notified when the - // socket is ready for reading. - bool want_read() const - { - return state_ == reading; - } - - // Notify that third party library that it should perform its read operation. - void do_read(asio::error_code& ec) - { - if (std::size_t len = socket_.read_some(asio::buffer(data_), ec)) - { - write_buffer_ = asio::buffer(data_, len); - state_ = writing; - } - } - - // Returns true if the third party library wants to be notified when the - // socket is ready for writing. - bool want_write() const - { - return state_ == writing; - } - - // Notify that third party library that it should perform its write operation. - void do_write(asio::error_code& ec) - { - if (std::size_t len = socket_.write_some( - asio::buffer(write_buffer_), ec)) - { - write_buffer_ = write_buffer_ + len; - state_ = asio::buffer_size(write_buffer_) > 0 ? writing : reading; - } - } - -private: - tcp::socket& socket_; - enum { reading, writing } state_; - boost::array data_; - asio::const_buffer write_buffer_; -}; - -} // namespace third_party_lib - -// The glue between asio's sockets and the third party library. -class connection - : public boost::enable_shared_from_this -{ -public: - typedef boost::shared_ptr pointer; - - static pointer create(const asio::any_io_executor& ex) - { - return pointer(new connection(ex)); - } - - tcp::socket& socket() - { - return socket_; - } - - void start() - { - // Put the socket into non-blocking mode. - socket_.non_blocking(true); - - start_operations(); - } - -private: - connection(const asio::any_io_executor& ex) - : socket_(ex), - session_impl_(socket_), - read_in_progress_(false), - write_in_progress_(false) - { - } - - void start_operations() - { - // Start a read operation if the third party library wants one. - if (session_impl_.want_read() && !read_in_progress_) - { - read_in_progress_ = true; - socket_.async_wait(tcp::socket::wait_read, - boost::bind(&connection::handle_read, - shared_from_this(), - asio::placeholders::error)); - } - - // Start a write operation if the third party library wants one. - if (session_impl_.want_write() && !write_in_progress_) - { - write_in_progress_ = true; - socket_.async_wait(tcp::socket::wait_write, - boost::bind(&connection::handle_write, - shared_from_this(), - asio::placeholders::error)); - } - } - - void handle_read(asio::error_code ec) - { - read_in_progress_ = false; - - // Notify third party library that it can perform a read. - if (!ec) - session_impl_.do_read(ec); - - // The third party library successfully performed a read on the socket. - // Start new read or write operations based on what it now wants. - if (!ec || ec == asio::error::would_block) - start_operations(); - - // Otherwise, an error occurred. Closing the socket cancels any outstanding - // asynchronous read or write operations. The connection object will be - // destroyed automatically once those outstanding operations complete. - else - socket_.close(); - } - - void handle_write(asio::error_code ec) - { - write_in_progress_ = false; - - // Notify third party library that it can perform a write. - if (!ec) - session_impl_.do_write(ec); - - // The third party library successfully performed a write on the socket. - // Start new read or write operations based on what it now wants. - if (!ec || ec == asio::error::would_block) - start_operations(); - - // Otherwise, an error occurred. Closing the socket cancels any outstanding - // asynchronous read or write operations. The connection object will be - // destroyed automatically once those outstanding operations complete. - else - socket_.close(); - } - -private: - tcp::socket socket_; - third_party_lib::session session_impl_; - bool read_in_progress_; - bool write_in_progress_; -}; - -class server -{ -public: - server(asio::io_context& io_context, unsigned short port) - : acceptor_(io_context, tcp::endpoint(tcp::v4(), port)) - { - start_accept(); - } - -private: - void start_accept() - { - connection::pointer new_connection = - connection::create(acceptor_.get_executor()); - - acceptor_.async_accept(new_connection->socket(), - boost::bind(&server::handle_accept, this, new_connection, - asio::placeholders::error)); - } - - void handle_accept(connection::pointer new_connection, - const asio::error_code& error) - { - if (!error) - { - new_connection->start(); - } - - start_accept(); - } - - tcp::acceptor acceptor_; -}; - -int main(int argc, char* argv[]) -{ - try - { - if (argc != 2) - { - std::cerr << "Usage: third_party_lib \n"; - return 1; - } - - asio::io_context io_context; - - using namespace std; // For atoi. - server s(io_context, atoi(argv[1])); - - io_context.run(); - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - } - - return 0; -} diff --git a/asio/src/examples/cpp03/socks4/.gitignore b/asio/src/examples/cpp03/socks4/.gitignore deleted file mode 100644 index e11e0de344..0000000000 --- a/asio/src/examples/cpp03/socks4/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -.deps -.dirstamp -*.o -*.obj -*.exe -sync_client -*.ilk -*.manifest -*.pdb -*.tds diff --git a/asio/src/examples/cpp03/socks4/socks4.hpp b/asio/src/examples/cpp03/socks4/socks4.hpp deleted file mode 100644 index 6e0c26761d..0000000000 --- a/asio/src/examples/cpp03/socks4/socks4.hpp +++ /dev/null @@ -1,144 +0,0 @@ -// -// socks4.hpp -// ~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef SOCKS4_HPP -#define SOCKS4_HPP - -#include -#include -#include - -namespace socks4 { - -const unsigned char version = 0x04; - -class request -{ -public: - enum command_type - { - connect = 0x01, - bind = 0x02 - }; - - request(command_type cmd, const asio::ip::tcp::endpoint& endpoint, - const std::string& user_id) - : version_(version), - command_(cmd), - user_id_(user_id), - null_byte_(0) - { - // Only IPv4 is supported by the SOCKS 4 protocol. - if (endpoint.protocol() != asio::ip::tcp::v4()) - { - throw asio::system_error( - asio::error::address_family_not_supported); - } - - // Convert port number to network byte order. - unsigned short port = endpoint.port(); - port_high_byte_ = (port >> 8) & 0xff; - port_low_byte_ = port & 0xff; - - // Save IP address in network byte order. - address_ = endpoint.address().to_v4().to_bytes(); - } - - boost::array buffers() const - { - boost::array bufs = - { - { - asio::buffer(&version_, 1), - asio::buffer(&command_, 1), - asio::buffer(&port_high_byte_, 1), - asio::buffer(&port_low_byte_, 1), - asio::buffer(address_), - asio::buffer(user_id_), - asio::buffer(&null_byte_, 1) - } - }; - return bufs; - } - -private: - unsigned char version_; - unsigned char command_; - unsigned char port_high_byte_; - unsigned char port_low_byte_; - asio::ip::address_v4::bytes_type address_; - std::string user_id_; - unsigned char null_byte_; -}; - -class reply -{ -public: - enum status_type - { - request_granted = 0x5a, - request_failed = 0x5b, - request_failed_no_identd = 0x5c, - request_failed_bad_user_id = 0x5d - }; - - reply() - : null_byte_(0), - status_() - { - } - - boost::array buffers() - { - boost::array bufs = - { - { - asio::buffer(&null_byte_, 1), - asio::buffer(&status_, 1), - asio::buffer(&port_high_byte_, 1), - asio::buffer(&port_low_byte_, 1), - asio::buffer(address_) - } - }; - return bufs; - } - - bool success() const - { - return null_byte_ == 0 && status_ == request_granted; - } - - unsigned char status() const - { - return status_; - } - - asio::ip::tcp::endpoint endpoint() const - { - unsigned short port = port_high_byte_; - port = (port << 8) & 0xff00; - port = port | port_low_byte_; - - asio::ip::address_v4 address(address_); - - return asio::ip::tcp::endpoint(address, port); - } - -private: - unsigned char null_byte_; - unsigned char status_; - unsigned char port_high_byte_; - unsigned char port_low_byte_; - asio::ip::address_v4::bytes_type address_; -}; - -} // namespace socks4 - -#endif // SOCKS4_HPP diff --git a/asio/src/examples/cpp03/socks4/sync_client.cpp b/asio/src/examples/cpp03/socks4/sync_client.cpp deleted file mode 100644 index 41616284e5..0000000000 --- a/asio/src/examples/cpp03/socks4/sync_client.cpp +++ /dev/null @@ -1,94 +0,0 @@ -// -// sync_client.cpp -// ~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include -#include -#include -#include -#include -#include -#include "socks4.hpp" - -using asio::ip::tcp; - -int main(int argc, char* argv[]) -{ - try - { - if (argc != 4) - { - std::cout << "Usage: sync_client \n"; - std::cout << "Examples:\n"; - std::cout << " sync_client 127.0.0.1 1080 chris\n"; - std::cout << " sync_client localhost socks chris\n"; - return 1; - } - - asio::io_context io_context; - - // Get a list of endpoints corresponding to the SOCKS 4 server name. - tcp::resolver resolver(io_context); - tcp::resolver::results_type endpoints = resolver.resolve(argv[1], argv[2]); - - // Try each endpoint until we successfully establish a connection to the - // SOCKS 4 server. - tcp::socket socket(io_context); - asio::connect(socket, endpoints); - - // Get an endpoint for the Boost website. This will be passed to the SOCKS - // 4 server. Explicitly specify IPv4 since SOCKS 4 does not support IPv6. - tcp::endpoint http_endpoint = - *resolver.resolve(tcp::v4(), "www.boost.org", "http").begin(); - - // Send the request to the SOCKS 4 server. - socks4::request socks_request( - socks4::request::connect, http_endpoint, argv[3]); - asio::write(socket, socks_request.buffers()); - - // Receive a response from the SOCKS 4 server. - socks4::reply socks_reply; - asio::read(socket, socks_reply.buffers()); - - // Check whether we successfully negotiated with the SOCKS 4 server. - if (!socks_reply.success()) - { - std::cout << "Connection failed.\n"; - std::cout << "status = 0x" << std::hex << socks_reply.status(); - return 1; - } - - // Form the HTTP request. We specify the "Connection: close" header so that - // the server will close the socket after transmitting the response. This - // will allow us to treat all data up until the EOF as the response. - std::string request = - "GET / HTTP/1.0\r\n" - "Host: www.boost.org\r\n" - "Accept: */*\r\n" - "Connection: close\r\n\r\n"; - - // Send the HTTP request. - asio::write(socket, asio::buffer(request)); - - // Read until EOF, writing data to output as we go. - boost::array response; - asio::error_code error; - while (std::size_t s = socket.read_some( - asio::buffer(response), error)) - std::cout.write(response.data(), s); - if (error != asio::error::eof) - throw asio::system_error(error); - } - catch (std::exception& e) - { - std::cout << "Exception: " << e.what() << "\n"; - } - - return 0; -} diff --git a/asio/src/examples/cpp03/spawn/.gitignore b/asio/src/examples/cpp03/spawn/.gitignore deleted file mode 100644 index 6b8a121e09..0000000000 --- a/asio/src/examples/cpp03/spawn/.gitignore +++ /dev/null @@ -1,12 +0,0 @@ -.deps -.dirstamp -parallel_grep -*.o -*.obj -*.exe -*_server -*_client -*.ilk -*.manifest -*.pdb -*.tds diff --git a/asio/src/examples/cpp03/spawn/echo_server.cpp b/asio/src/examples/cpp03/spawn/echo_server.cpp deleted file mode 100644 index f89046cd62..0000000000 --- a/asio/src/examples/cpp03/spawn/echo_server.cpp +++ /dev/null @@ -1,126 +0,0 @@ -// -// echo_server.cpp -// ~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using asio::ip::tcp; - -class session : public boost::enable_shared_from_this -{ -public: - explicit session(asio::io_context& io_context) - : strand_(asio::make_strand(io_context)), - socket_(io_context), - timer_(io_context) - { - } - - tcp::socket& socket() - { - return socket_; - } - - void go() - { - asio::spawn(strand_, - boost::bind(&session::echo, - shared_from_this(), boost::placeholders::_1), - asio::detached_t()); - asio::spawn(strand_, - boost::bind(&session::timeout, - shared_from_this(), boost::placeholders::_1), - asio::detached_t()); - } - -private: - void echo(asio::yield_context yield) - { - try - { - char data[128]; - for (;;) - { - timer_.expires_after(asio::chrono::seconds(10)); - std::size_t n = socket_.async_read_some(asio::buffer(data), yield); - asio::async_write(socket_, asio::buffer(data, n), yield); - } - } - catch (std::exception& e) - { - socket_.close(); - timer_.cancel(); - } - } - - void timeout(asio::yield_context yield) - { - while (socket_.is_open()) - { - asio::error_code ignored_ec; - timer_.async_wait(yield[ignored_ec]); - if (timer_.expiry() <= asio::steady_timer::clock_type::now()) - socket_.close(); - } - } - - asio::strand strand_; - tcp::socket socket_; - asio::steady_timer timer_; -}; - -void do_accept(asio::io_context& io_context, - unsigned short port, asio::yield_context yield) -{ - tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v4(), port)); - - for (;;) - { - asio::error_code ec; - boost::shared_ptr new_session(new session(io_context)); - acceptor.async_accept(new_session->socket(), yield[ec]); - if (!ec) new_session->go(); - } -} - -int main(int argc, char* argv[]) -{ - try - { - if (argc != 2) - { - std::cerr << "Usage: echo_server \n"; - return 1; - } - - asio::io_context io_context; - - asio::spawn(io_context, - boost::bind(do_accept, boost::ref(io_context), - atoi(argv[1]), boost::placeholders::_1), - asio::detached_t()); - - io_context.run(); - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - } - - return 0; -} diff --git a/asio/src/examples/cpp03/spawn/parallel_grep.cpp b/asio/src/examples/cpp03/spawn/parallel_grep.cpp deleted file mode 100644 index 5b369be1f4..0000000000 --- a/asio/src/examples/cpp03/spawn/parallel_grep.cpp +++ /dev/null @@ -1,93 +0,0 @@ -// -// parallel_grep.cpp -// ~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using asio::detached_t; -using asio::dispatch; -using asio::spawn; -using asio::strand; -using asio::thread_pool; -using asio::yield_context; - -void print_match(std::string input_file, std::string line) -{ - std::cout << input_file << ':' << line << std::endl; -} - -void search_file(std::string search_string, std::string input_file, - strand output_strand, yield_context yield) -{ - std::ifstream is(input_file.c_str()); - std::string line; - std::size_t line_num = 0; - while (std::getline(is, line)) - { - // If we find a match, send a message to the output. - if (line.find(search_string) != std::string::npos) - { - dispatch(output_strand, boost::bind(&print_match, input_file, line)); - } - - // Every so often we yield control to another coroutine. - if (++line_num % 10 == 0) - post(yield); - } -} - -int main(int argc, char* argv[]) -{ - try - { - if (argc < 2) - { - std::cerr << "Usage: parallel_grep \n"; - return 1; - } - - // We use a fixed size pool of threads for reading the input files. The - // number of threads is automatically determined based on the number of - // CPUs available in the system. - thread_pool pool; - - // To prevent the output from being garbled, we use a strand to synchronise - // printing. - strand output_strand(pool.get_executor()); - - // Spawn a new coroutine for each file specified on the command line. - std::string search_string = argv[1]; - for (int argn = 2; argn < argc; ++argn) - { - std::string input_file = argv[argn]; - spawn(pool, - boost::bind(&search_file, search_string, - input_file, output_strand, boost::placeholders::_1), - detached_t()); - } - - // Join the thread pool to wait for all the spawned tasks to complete. - pool.join(); - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - } - - return 0; -} diff --git a/asio/src/examples/cpp03/ssl/.gitignore b/asio/src/examples/cpp03/ssl/.gitignore deleted file mode 100644 index a67811253d..0000000000 --- a/asio/src/examples/cpp03/ssl/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -.deps -.dirstamp -*.o -*.obj -*.exe -server -client -*.ilk -*.manifest -*.pdb -*.tds diff --git a/asio/src/examples/cpp03/ssl/README b/asio/src/examples/cpp03/ssl/README deleted file mode 100644 index 5d4bc5c813..0000000000 --- a/asio/src/examples/cpp03/ssl/README +++ /dev/null @@ -1,8 +0,0 @@ -The passphrase for both the CA and server private keys is "test". - - -------------------------------------------------------------------------------- -Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) - -Distributed under the Boost Software License, Version 1.0. (See accompanying -file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) diff --git a/asio/src/examples/cpp03/ssl/ca.pem b/asio/src/examples/cpp03/ssl/ca.pem deleted file mode 100644 index 4580bc11bc..0000000000 --- a/asio/src/examples/cpp03/ssl/ca.pem +++ /dev/null @@ -1,50 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDVDCCAjygAwIBAgIUX3cVQ47QyJp7SOy0RPzP743W9MwwDQYJKoZIhvcNAQEL -BQAwOzELMAkGA1UEBhMCQVUxDDAKBgNVBAgMA05TVzEPMA0GA1UEBwwGU3lkbmV5 -MQ0wCwYDVQQKDARhc2lvMB4XDTIxMTExMTIxMTA1MloXDTI2MTExMDIxMTA1Mlow -OzELMAkGA1UEBhMCQVUxDDAKBgNVBAgMA05TVzEPMA0GA1UEBwwGU3lkbmV5MQ0w -CwYDVQQKDARhc2lvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyURD -LjKxTCkapmWhY0bP1NaaOPzIJTTB0dzREOlmRmBmiHpW7DaRx7qBm6jYDKQ7OCbz -30/j8K4TjHOLIwxzXhXMYTJOcN2giPHNUBvm9oEuDAhYgltArJQnBBEH+3C1hCIv -1+uhTWo0HpGXTeJnvboTZ1YgmbOgr6lMhNiu9QmPX885DxWf6sDq8mRgCDX2x8sk -Ls0HuLSo88Osjx532yEhnrZgexsByhoRD3yrKHV5mWpaunk5BMsP/XMuQHayFmbO -siqnHJoL1znGVH003PcBGmEDmoIUqhLiBi2gWGu1pmckP9loqQUTEn0aLOVclHf4 -slWq344zh4tJCpQMfQIDAQABo1AwTjAdBgNVHQ4EFgQUfiX1CMQrGDi9mIBAg9cg -m0RwLJUwHwYDVR0jBBgwFoAUfiX1CMQrGDi9mIBAg9cgm0RwLJUwDAYDVR0TBAUw -AwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAnDnVNSb8z/pNFaZ6YAZ+ukfNT3jjbGm1 -10BOLqJj8s5A8/JkwjaWhky/DuGXDywgEvzXC18aNAxASeqO8h9pAZtszu6NWB4s -h3r+dEQakMacxrZ+jBL/cYLrUv9r3KMPKxaDnplkamqFA/9eNmoV7vDyGtGPZuD6 -oTROtQqqDSrxthCkqnibAfusi7RmlCdvJa0kVK7krKJZAhi8W9f32+lBPv9oq3Ns -dAxnOj/D3UnhNoIt0EdjqUdLo2U39dt5s5Syj2rFUAgfbc02Rwx65kq8AjTRlW/M -KDpGsifwIB8b7wActMUO8c3GptptNVWmFm5+Mmk54P//P3tIAx9KXw== ------END CERTIFICATE----- ------BEGIN ENCRYPTED PRIVATE KEY----- -MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIPcVUeQ7ZElgCAggA -MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECGKlFVN6/gIlBIIEyJPeknsA5dvV -WK27AZzs4wM6WrsD6ba+kPJyZTpon5pn4eoTiw4UCvo7C+21G9jCqbIbDrgTWHwH -zu6YrBFTZgRUpdLkLsyUsp4UJrZ8xJ7N/jWlG763CyluFE5oBFLz2Vt/DSDSaWdA -sKdxua/1kvw+KYoDqlObMFIspM5TrndcMnWkOgyvQAvnH0NZXFFBa4QGFrwWDrCo -m12CzMLwaPMrNFBffCTqZnL1AajT+EYqPTi+cQ5mkRpZ2cuzhdug2eki1KkD12ZN -3d8Ehl8bfbLEqRE/HnggleRRt7ia1xkzruqQp14JA2UsrioGMF5nvWgWrbyHfpui -KrCsDwDelrArW/GCki53QBQMuH8Q1YmoNrRZwlG257eA1LiJvmxRyIjKYu0RP+Q8 -EOldycy51VsPVPApUbv9r4IJldrIJiwlmRxxM36uKtFhfojnsWzJORDYI8C37uKi -UEPiD4GSEH6C0lGO94IoZPjl9z/rZ0qZx1VRHl3nxZc0AQvvj9bWMbyRwsgb6wod -P8JSy6uEib9UxuenNHzTd48GcNhJbhOqd4IV0XKhi8W1Kil3mMdc3QAwKaLTx12/ -1GrbMui061uyeM6Rf6Xao0PApDnUNmxcFSTsoarG0yH7Q0WZMgKTDCCGhhtZKlE6 -x7pRsnxiFaIpoh32EVIRI+ZXh2rXBcwa2ew0aEccRXtPFvcmdjevkrHuCggc+M+Y -seFqTHVGWf8eS6o08w095DboD0vFpZXZMRfycTbA7BiE4NYE/uc7v5cH3Ax9l2ef -zG7o9idDt+/RX7OcetxDFw4eQbq7PfjvrfXS1DcRUEyJ04emh7oxlkAUUNsFtabN -T0ggvHxcQWkYRE5oPlkbgpwKpK4LDcApXKFwCDKPur2W5Q7KHRfDLtSvZvYarJum -8j2pGpEis/bdTih29ofNsX6a0Yo5Tlj+9+1c/6/Xi7XvRk/Vbgkoa3iVQ3ckdCuZ -vO7cRYZBBs6W/Ti3hWFzPEX9FfcnSUp9bEnH4ASnmUcp8PDBJYeaI6HqpO3XbkbF -l70eDNakd2cDNjQzkFpBT7HO+HtqU3xNt9K0z2gMB7iTDVFyIzh26joCR2O8tiqS -wUJFkoLPb74GSB7WzE+gb4jXX6n9609PUoR3f896mM34uX3CsY8lA+/0ZGpHnFDA -ToKdmz6WKIAw0E20nyzLuLwPZgj7HLcR7zza4raipe9QxIdyJr5O+jzGt+OjSM9b -K1agibRE5DChqQ+P+ikOc6nG7UNyn+lKSjGEbwuzi8F0iugMgcTc/vYO8OWDNGpd -D1euA5OuVPdfatFa16Fyr4MJJIfE83C4/kSj05fdoyb6pJkOjHhUppVMe+ES5kwl -YI8RES2XVJzUSxnWsIM613YlMgIZ9xgcuIADnO7gaKJ4RQG+9wJ853Uo4+n89K7F -Y6KzihuYAUkbAw1pPo1TODom7A/gB9stqRUSQlZWmIgtnJ8wPjt/we0gzPM8LQzb -ye4KOLjH5iquFc4MU4TtN3gvp9P5R9UFrGeMImS5eMUmBQHckDNdIAtMj7M1wUpR -JVrzDXWDjC21sLn95NtNMPb+FRlt/biTV3IE3ZmX0kbuCRoH7b7hhR41Zpoajwl0 -FqYigB5gnVodGUWuBgDUqA== ------END ENCRYPTED PRIVATE KEY----- diff --git a/asio/src/examples/cpp03/ssl/client.cpp b/asio/src/examples/cpp03/ssl/client.cpp deleted file mode 100644 index 3ff20aa887..0000000000 --- a/asio/src/examples/cpp03/ssl/client.cpp +++ /dev/null @@ -1,157 +0,0 @@ -// -// client.cpp -// ~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include -#include -#include -#include "asio.hpp" -#include "asio/ssl.hpp" - -enum { max_length = 1024 }; - -class client -{ -public: - client(asio::io_context& io_context, - asio::ssl::context& context, - asio::ip::tcp::resolver::results_type endpoints) - : socket_(io_context, context) - { - socket_.set_verify_mode(asio::ssl::verify_peer); - socket_.set_verify_callback( - boost::bind(&client::verify_certificate, this, - boost::placeholders::_1, boost::placeholders::_2)); - - asio::async_connect(socket_.lowest_layer(), endpoints, - boost::bind(&client::handle_connect, this, - asio::placeholders::error)); - } - - bool verify_certificate(bool preverified, - asio::ssl::verify_context& ctx) - { - // The verify callback can be used to check whether the certificate that is - // being presented is valid for the peer. For example, RFC 2818 describes - // the steps involved in doing this for HTTPS. Consult the OpenSSL - // documentation for more details. Note that the callback is called once - // for each certificate in the certificate chain, starting from the root - // certificate authority. - - // In this example we will simply print the certificate's subject name. - char subject_name[256]; - X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle()); - X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256); - std::cout << "Verifying " << subject_name << "\n"; - - return preverified; - } - - void handle_connect(const asio::error_code& error) - { - if (!error) - { - socket_.async_handshake(asio::ssl::stream_base::client, - boost::bind(&client::handle_handshake, this, - asio::placeholders::error)); - } - else - { - std::cout << "Connect failed: " << error.message() << "\n"; - } - } - - void handle_handshake(const asio::error_code& error) - { - if (!error) - { - std::cout << "Enter message: "; - std::cin.getline(request_, max_length); - size_t request_length = strlen(request_); - - asio::async_write(socket_, - asio::buffer(request_, request_length), - boost::bind(&client::handle_write, this, - asio::placeholders::error, - asio::placeholders::bytes_transferred)); - } - else - { - std::cout << "Handshake failed: " << error.message() << "\n"; - } - } - - void handle_write(const asio::error_code& error, - size_t bytes_transferred) - { - if (!error) - { - asio::async_read(socket_, - asio::buffer(reply_, bytes_transferred), - boost::bind(&client::handle_read, this, - asio::placeholders::error, - asio::placeholders::bytes_transferred)); - } - else - { - std::cout << "Write failed: " << error.message() << "\n"; - } - } - - void handle_read(const asio::error_code& error, - size_t bytes_transferred) - { - if (!error) - { - std::cout << "Reply: "; - std::cout.write(reply_, bytes_transferred); - std::cout << "\n"; - } - else - { - std::cout << "Read failed: " << error.message() << "\n"; - } - } - -private: - asio::ssl::stream socket_; - char request_[max_length]; - char reply_[max_length]; -}; - -int main(int argc, char* argv[]) -{ - try - { - if (argc != 3) - { - std::cerr << "Usage: client \n"; - return 1; - } - - asio::io_context io_context; - - asio::ip::tcp::resolver resolver(io_context); - asio::ip::tcp::resolver::results_type endpoints = - resolver.resolve(argv[1], argv[2]); - - asio::ssl::context ctx(asio::ssl::context::sslv23); - ctx.load_verify_file("ca.pem"); - - client c(io_context, ctx, endpoints); - - io_context.run(); - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - } - - return 0; -} diff --git a/asio/src/examples/cpp03/ssl/dh4096.pem b/asio/src/examples/cpp03/ssl/dh4096.pem deleted file mode 100644 index dc2559c5f8..0000000000 --- a/asio/src/examples/cpp03/ssl/dh4096.pem +++ /dev/null @@ -1,25 +0,0 @@ ------BEGIN X9.42 DH PARAMETERS----- -MIIELQKCAgEA8eEBgatlTk0QKIwUqHsteHJXzEr0xAW7RLeNid8DdGjTnFw68eV+ -s1YbipEqQVTFG+VZPaof9v0CH2KOdbgWD0KRPC49HB8O/wARFKpy5eJltVe1r07w -+V1Vjciqkh/vGq/yFQsbqwyWJy6AelsbHdSC9Bg9pmu4+pbVGW15zK7PkfjfoO9V -JYbhdqFIPg+9NRRWsl/U9UoyeeIGImI9I4k3fqtv311C6VVErFZylCj7nn45L7IY -GfPcCO5E8FD6EqBv5WnhMNYHMJu9brRvOoAyAyWprqR+aVzHd+DFamDQdsuQjKTk -3+r07znWJfjp6FVTzR5SvjrKg1knK5TibIksoKOlsFZ06bGkFWHjqXNAKhnSpCiU -GJd0qe7pTD+TGQJGWskJpoph+tkICUa+6MyzP9+U6T9hISIY/BpVuWn/iwdLqsvV -s5bg2RjRraww/4Rjm0NyEOTk2MxaLB9gcyu6zcrhX5XRiMgt+jhKwEMwJCEJYkxn -C0yv08A5v6RceFm1jY+8FT0IzRqsWIGV7beNdqtE0B4LBTuN1yQ6x8CKEb6mbIHG -d0XLGppELhD8QUwAr5HiVGTAsS9JlMGgXVkyDtxrVSeS1zHWt77skRQ9UlfJfYMm -5wxHj5QCdQ7ma3oMMZBZutNlkevMzYHIxwqhZstf4ud0j0VMftwZ3GMCggIBAJL7 -cU6/YSxzYDGUcPc6WGT+FAghR0LdhT3Q3Xz1rQRBwSSMPm9NZhyJC3fb+hBl/44X -AHOu1/3dYIWlXPMuHZZdtlt+hkD/sIob16By20Z0p81Kvh3HQglVDJGlFzTmQbTd -CM/EP8eJFiNeMcJB0RgeKyzikRsV4r/acZZM56swTlsRvSDFMh3v9YyYTZbCTwxm -PIVOsxI8uBoWRCzY3yWzjmlZ2u5TR+Z0IVonmNqk6XAKRgxV12YfQVXzzpPZQA9S -GHoD/NQoMdBAi3p4pLEYJ5qMRLYPQbBfSNu5eP9e5uZOiBp/28bVnzEelDGuFupr -lvywkZEVL1KaYtZ/dGkPFXt+A7mNsw5xeDTRjgL4uUJvCNIkjgVEfIrLdUf5IVsU -V8BgunAvgfH+Hy6Tx89v/QGsUWJPhjkSZnXwJ7Ipcsm+Zg0zAZwKDZEQtDLXVPRL -OfCfXMXvlw2u6OHlhSbqO69zZG3dJTlcnjy06n4JYcUim7Mj3Kduige6VWofeEk9 -M/kHrPqNdFE5tHLh2nHcw9yExKHN+l/OUGAvNDfOVS+S+fNSKT0RfC9dMpHLN+Ok -fGuskGzLQAVYF+DYEcnJ++0LEFtd0J381ndSc0iJuH60rKDTqxoRqv7lcdwLFlEV -sQSRoas8s+y+b3FfSu7j0p44qLG9oxZ/WFcWnuUyAiEAjvAD9p3bw8AH0s7dUrX/ -RT1Ge+J/n0tlsgw+LY3zafE= ------END X9.42 DH PARAMETERS----- diff --git a/asio/src/examples/cpp03/ssl/server.cpp b/asio/src/examples/cpp03/ssl/server.cpp deleted file mode 100644 index 447d94088c..0000000000 --- a/asio/src/examples/cpp03/ssl/server.cpp +++ /dev/null @@ -1,170 +0,0 @@ -// -// server.cpp -// ~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include -#include -#include -#include "asio.hpp" -#include "asio/ssl.hpp" - -typedef asio::ssl::stream ssl_socket; - -class session -{ -public: - session(asio::io_context& io_context, - asio::ssl::context& context) - : socket_(io_context, context) - { - } - - ssl_socket::lowest_layer_type& socket() - { - return socket_.lowest_layer(); - } - - void start() - { - socket_.async_handshake(asio::ssl::stream_base::server, - boost::bind(&session::handle_handshake, this, - asio::placeholders::error)); - } - - void handle_handshake(const asio::error_code& error) - { - if (!error) - { - socket_.async_read_some(asio::buffer(data_, max_length), - boost::bind(&session::handle_read, this, - asio::placeholders::error, - asio::placeholders::bytes_transferred)); - } - else - { - delete this; - } - } - - void handle_read(const asio::error_code& error, - size_t bytes_transferred) - { - if (!error) - { - asio::async_write(socket_, - asio::buffer(data_, bytes_transferred), - boost::bind(&session::handle_write, this, - asio::placeholders::error)); - } - else - { - delete this; - } - } - - void handle_write(const asio::error_code& error) - { - if (!error) - { - socket_.async_read_some(asio::buffer(data_, max_length), - boost::bind(&session::handle_read, this, - asio::placeholders::error, - asio::placeholders::bytes_transferred)); - } - else - { - delete this; - } - } - -private: - ssl_socket socket_; - enum { max_length = 1024 }; - char data_[max_length]; -}; - -class server -{ -public: - server(asio::io_context& io_context, unsigned short port) - : io_context_(io_context), - acceptor_(io_context, - asio::ip::tcp::endpoint(asio::ip::tcp::v4(), port)), - context_(asio::ssl::context::sslv23) - { - context_.set_options( - asio::ssl::context::default_workarounds - | asio::ssl::context::no_sslv2 - | asio::ssl::context::single_dh_use); - context_.set_password_callback(boost::bind(&server::get_password, this)); - context_.use_certificate_chain_file("server.pem"); - context_.use_private_key_file("server.pem", asio::ssl::context::pem); - context_.use_tmp_dh_file("dh4096.pem"); - - start_accept(); - } - - std::string get_password() const - { - return "test"; - } - - void start_accept() - { - session* new_session = new session(io_context_, context_); - acceptor_.async_accept(new_session->socket(), - boost::bind(&server::handle_accept, this, new_session, - asio::placeholders::error)); - } - - void handle_accept(session* new_session, - const asio::error_code& error) - { - if (!error) - { - new_session->start(); - } - else - { - delete new_session; - } - - start_accept(); - } - -private: - asio::io_context& io_context_; - asio::ip::tcp::acceptor acceptor_; - asio::ssl::context context_; -}; - -int main(int argc, char* argv[]) -{ - try - { - if (argc != 2) - { - std::cerr << "Usage: server \n"; - return 1; - } - - asio::io_context io_context; - - using namespace std; // For atoi. - server s(io_context, atoi(argv[1])); - - io_context.run(); - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - } - - return 0; -} diff --git a/asio/src/examples/cpp03/ssl/server.pem b/asio/src/examples/cpp03/ssl/server.pem deleted file mode 100644 index a7bcba738a..0000000000 --- a/asio/src/examples/cpp03/ssl/server.pem +++ /dev/null @@ -1,99 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDDjCCAfYCFGGcJXlIeQHiq/qOakbISU5cihPvMA0GCSqGSIb3DQEBCwUAMDsx -CzAJBgNVBAYTAkFVMQwwCgYDVQQIDANOU1cxDzANBgNVBAcMBlN5ZG5leTENMAsG -A1UECgwEYXNpbzAeFw0yMTExMTEyMTExNDRaFw0yNjExMTAyMTExNDRaMEwxCzAJ -BgNVBAYTAkFVMQwwCgYDVQQIDANOU1cxDzANBgNVBAcMBlN5ZG5leTENMAsGA1UE -CgwEYXNpbzEPMA0GA1UECwwGc2VydmVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAu67TzZCFNTZ5c1gKwXfdTH3bP0OB5n6dqXGK6jkPb699dyM4oPtY -2f+OyxJspk8D5pX6HuZ+hLGAsHxfCN+A3RegVZJCR/gXrrMPl/6PfDxtkeFXWy+6 -NAPxqppMj8gbX/czTdNFwgW4J8/RLyH53utjAGQtCRr97EbBOsTSeOmyAxbw4mRt -EvHjacKFcSZzJDlyxCia37791MulZ4lwOZZlke5NzoOqkBIAusQgg7fMWDvH27PD -T+taIyBsYTVJWHf5kMklAlWYXZvNjZp/QGt13lDORg2aSc/P2pE4iLyhbZcpuW+W -nHB7IY1wjDL55/ORCjz3VlNIAMXHP5YQxwIDAQABMA0GCSqGSIb3DQEBCwUAA4IB -AQC3iiwQTgDP4ixulisYIGlJb8iuhxH9G41hm8dF/1qlIfXWxsbjb+g7M5U/3JCb -fwCGoz7uBdj/CKkIb5wx83GVC1yVLbNSvCIS827qxic4GACEYGGAy4Ub5tUCQrLr -JUQTP1WVJcgiKvk7OAcXdA+k/CcNXH153gUPDZz+/BedXe2VbM6LDsqPeSxXfbZN -AWXARAuly7cQk/xkYkPldRRhx4htNCbnkG1qyEqNcYQN1SY9Qhbrm2HkAUntzQ7G -umo4JdbIX6MJ5fYNs+yN/lJB7PiJP8Mz1AtOz4x9JxcLyuB6sapT8Tj53n9g/+m1 -Tqd8lHpWe6oM0sgdWfzdBNir ------END CERTIFICATE----- ------BEGIN RSA PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: DES-EDE3-CBC,9E0E6B9970E055F1 - -oFvN3t50B2TSeNsRo1vwhVYlMmt0w3MD3Ar75fti4fRhBrWoH4rBPrSouWK4OMDK -CakfVhzJIEvaMav843grS4V+ooAsfnAtiQiQj+5xjZ8PlCuWir5gyjgqeN4zN6ZT -2s/oEy5Kx7Ru5AWMkv+NPW5l3iS3c+Hupfb/auITwECSCCsCBxgNtJ8z0iXjv9Dr -hqvqcI+4F5DSiol3QhitbpQ/k2PKu92AZhPcr9e5HrqeUD7aqfX2q3i+tnJvxC93 -0mvy133bX2ZAGAKMheW/GuzcETfwU80wvmrwHXI9rnuAUaJhrDiIZQ79gubZ0Pcm -w4Y6Z5xxeErb7zKBi+pHKst8MJ7rfSz/N878su6cpESRC/w1paVX7m8/q61kzBkj -+h2qe9DupXBejQkriN+Z858nFtBKbWlFsmAg1FLZonworTUfV2c7S9yzMV/29VOE -T0Bt8BU1Hp+bCjreF4JGbnUJnRQoASpisfUkrD6Ar4GI56Edkkx6hkF0cXdcvfCN -qyhxzcvf/aV1M2kcpBRX9mIfjoFMFNz7uRIxyqPLaDkigwJemoaBo3n9/W5F7N7B -AGNEZ3QhUlc8EyWpGRZRzMevu5wdz1b2+MqItOhPXUo2XcLEj2iFkVDdbj/d9jQH -9ZIe4hQTSf784tAzt2Jp2RHmm22390GB1jdzG/CzbGlAKmaTTEe4FJcd/eLOEZuD -4+iFsEb/bWcCyXkBKkdEoDDMJW8xi5d/1ezJM03nqhvkekDqyhJUJPCbmY1SCX1X -4AO40jJmWQxwj26Pnnncacz4tuecZNqovz+POpKQSIctrQSV4wgf35137KBt7/O7 -EU0N7Qj4xTigyGkEHCZt7BgD8fFrxiP1OkUmFRHEE7Dxiagz6omJV8ien+p9wIgS -QcqkJlgKMwVepjuCuEyvg5oIkAPvp24yhePSJkEvvoDLvM2Kub/CM+UkN8dSgsZk -+ZBE9Oi62AWWow8/ib8Um5DNIEZsq+5CQLeBG7f5kTIBAoA9UceaEgbxzOVUCBcX -L7QsJ3pZ/ei1qx/9tChO/OXa9tleXcjGg7/q/6i6pUyZuqZlt+hk+3HtFmTXIjsM -chbUSMEJ2isv9MDamTtunt9N92A6OxUkAs68kCO/bzotldXMKZVjOohNnML5q/3U -vpsuN8NNwaNHCAM7pjols4V7ebX1lDZFR1hbj+szKMhVKzFfig1lRHafgRrR6H6P -mUK16lKzUbmvwv2IU/3wck+4UNeB/+lRmfAfBasQytnbt+5fwwNkVSrDY2Kxe0nz -2k3eIYST+ygxGuNrW9rnFbBpTJb0OE5cpgun8xxDE91AmL550AcZff+9ulDBhZg1 -eMoKUALlEdDNPffVTH8Iupn0jMnJsjXynztcEVhx4h2aA5X6/2i035uEybCn33qP -J7g30oe2C69BSC0YmkT3MjF6Wrhy+M8dU0dDggRhY6JSS8wESvwGenaPi7SZlbxb -Elmc44bHros1YfGl/xDdhju134/aMBG1GlZlReI+Rwnp9DCp04xiiJb9YKyUNaGY -7BTGWyie/WYYKbX1ZlxqWA9jxow8PM1XYHuanau1/aYT16L7E83HG3qkyuFIlLJh ------END RSA PRIVATE KEY----- ------BEGIN CERTIFICATE----- -MIIDVDCCAjygAwIBAgIUX3cVQ47QyJp7SOy0RPzP743W9MwwDQYJKoZIhvcNAQEL -BQAwOzELMAkGA1UEBhMCQVUxDDAKBgNVBAgMA05TVzEPMA0GA1UEBwwGU3lkbmV5 -MQ0wCwYDVQQKDARhc2lvMB4XDTIxMTExMTIxMTA1MloXDTI2MTExMDIxMTA1Mlow -OzELMAkGA1UEBhMCQVUxDDAKBgNVBAgMA05TVzEPMA0GA1UEBwwGU3lkbmV5MQ0w -CwYDVQQKDARhc2lvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyURD -LjKxTCkapmWhY0bP1NaaOPzIJTTB0dzREOlmRmBmiHpW7DaRx7qBm6jYDKQ7OCbz -30/j8K4TjHOLIwxzXhXMYTJOcN2giPHNUBvm9oEuDAhYgltArJQnBBEH+3C1hCIv -1+uhTWo0HpGXTeJnvboTZ1YgmbOgr6lMhNiu9QmPX885DxWf6sDq8mRgCDX2x8sk -Ls0HuLSo88Osjx532yEhnrZgexsByhoRD3yrKHV5mWpaunk5BMsP/XMuQHayFmbO -siqnHJoL1znGVH003PcBGmEDmoIUqhLiBi2gWGu1pmckP9loqQUTEn0aLOVclHf4 -slWq344zh4tJCpQMfQIDAQABo1AwTjAdBgNVHQ4EFgQUfiX1CMQrGDi9mIBAg9cg -m0RwLJUwHwYDVR0jBBgwFoAUfiX1CMQrGDi9mIBAg9cgm0RwLJUwDAYDVR0TBAUw -AwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAnDnVNSb8z/pNFaZ6YAZ+ukfNT3jjbGm1 -10BOLqJj8s5A8/JkwjaWhky/DuGXDywgEvzXC18aNAxASeqO8h9pAZtszu6NWB4s -h3r+dEQakMacxrZ+jBL/cYLrUv9r3KMPKxaDnplkamqFA/9eNmoV7vDyGtGPZuD6 -oTROtQqqDSrxthCkqnibAfusi7RmlCdvJa0kVK7krKJZAhi8W9f32+lBPv9oq3Ns -dAxnOj/D3UnhNoIt0EdjqUdLo2U39dt5s5Syj2rFUAgfbc02Rwx65kq8AjTRlW/M -KDpGsifwIB8b7wActMUO8c3GptptNVWmFm5+Mmk54P//P3tIAx9KXw== ------END CERTIFICATE----- ------BEGIN ENCRYPTED PRIVATE KEY----- -MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIPcVUeQ7ZElgCAggA -MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECGKlFVN6/gIlBIIEyJPeknsA5dvV -WK27AZzs4wM6WrsD6ba+kPJyZTpon5pn4eoTiw4UCvo7C+21G9jCqbIbDrgTWHwH -zu6YrBFTZgRUpdLkLsyUsp4UJrZ8xJ7N/jWlG763CyluFE5oBFLz2Vt/DSDSaWdA -sKdxua/1kvw+KYoDqlObMFIspM5TrndcMnWkOgyvQAvnH0NZXFFBa4QGFrwWDrCo -m12CzMLwaPMrNFBffCTqZnL1AajT+EYqPTi+cQ5mkRpZ2cuzhdug2eki1KkD12ZN -3d8Ehl8bfbLEqRE/HnggleRRt7ia1xkzruqQp14JA2UsrioGMF5nvWgWrbyHfpui -KrCsDwDelrArW/GCki53QBQMuH8Q1YmoNrRZwlG257eA1LiJvmxRyIjKYu0RP+Q8 -EOldycy51VsPVPApUbv9r4IJldrIJiwlmRxxM36uKtFhfojnsWzJORDYI8C37uKi -UEPiD4GSEH6C0lGO94IoZPjl9z/rZ0qZx1VRHl3nxZc0AQvvj9bWMbyRwsgb6wod -P8JSy6uEib9UxuenNHzTd48GcNhJbhOqd4IV0XKhi8W1Kil3mMdc3QAwKaLTx12/ -1GrbMui061uyeM6Rf6Xao0PApDnUNmxcFSTsoarG0yH7Q0WZMgKTDCCGhhtZKlE6 -x7pRsnxiFaIpoh32EVIRI+ZXh2rXBcwa2ew0aEccRXtPFvcmdjevkrHuCggc+M+Y -seFqTHVGWf8eS6o08w095DboD0vFpZXZMRfycTbA7BiE4NYE/uc7v5cH3Ax9l2ef -zG7o9idDt+/RX7OcetxDFw4eQbq7PfjvrfXS1DcRUEyJ04emh7oxlkAUUNsFtabN -T0ggvHxcQWkYRE5oPlkbgpwKpK4LDcApXKFwCDKPur2W5Q7KHRfDLtSvZvYarJum -8j2pGpEis/bdTih29ofNsX6a0Yo5Tlj+9+1c/6/Xi7XvRk/Vbgkoa3iVQ3ckdCuZ -vO7cRYZBBs6W/Ti3hWFzPEX9FfcnSUp9bEnH4ASnmUcp8PDBJYeaI6HqpO3XbkbF -l70eDNakd2cDNjQzkFpBT7HO+HtqU3xNt9K0z2gMB7iTDVFyIzh26joCR2O8tiqS -wUJFkoLPb74GSB7WzE+gb4jXX6n9609PUoR3f896mM34uX3CsY8lA+/0ZGpHnFDA -ToKdmz6WKIAw0E20nyzLuLwPZgj7HLcR7zza4raipe9QxIdyJr5O+jzGt+OjSM9b -K1agibRE5DChqQ+P+ikOc6nG7UNyn+lKSjGEbwuzi8F0iugMgcTc/vYO8OWDNGpd -D1euA5OuVPdfatFa16Fyr4MJJIfE83C4/kSj05fdoyb6pJkOjHhUppVMe+ES5kwl -YI8RES2XVJzUSxnWsIM613YlMgIZ9xgcuIADnO7gaKJ4RQG+9wJ853Uo4+n89K7F -Y6KzihuYAUkbAw1pPo1TODom7A/gB9stqRUSQlZWmIgtnJ8wPjt/we0gzPM8LQzb -ye4KOLjH5iquFc4MU4TtN3gvp9P5R9UFrGeMImS5eMUmBQHckDNdIAtMj7M1wUpR -JVrzDXWDjC21sLn95NtNMPb+FRlt/biTV3IE3ZmX0kbuCRoH7b7hhR41Zpoajwl0 -FqYigB5gnVodGUWuBgDUqA== ------END ENCRYPTED PRIVATE KEY----- diff --git a/asio/src/examples/cpp03/timeouts/.gitignore b/asio/src/examples/cpp03/timeouts/.gitignore deleted file mode 100644 index dda7f39c3c..0000000000 --- a/asio/src/examples/cpp03/timeouts/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -.deps -.dirstamp -*.o -*.obj -*.exe -*_client -server -*.ilk -*.manifest -*.pdb -*.tds diff --git a/asio/src/examples/cpp03/timeouts/async_tcp_client.cpp b/asio/src/examples/cpp03/timeouts/async_tcp_client.cpp deleted file mode 100644 index edc6ad55f5..0000000000 --- a/asio/src/examples/cpp03/timeouts/async_tcp_client.cpp +++ /dev/null @@ -1,311 +0,0 @@ -// -// async_tcp_client.cpp -// ~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include "asio/buffer.hpp" -#include "asio/io_context.hpp" -#include "asio/ip/tcp.hpp" -#include "asio/read_until.hpp" -#include "asio/steady_timer.hpp" -#include "asio/write.hpp" -#include -#include -#include - -using asio::steady_timer; -using asio::ip::tcp; - -// -// This class manages socket timeouts by applying the concept of a deadline. -// Some asynchronous operations are given deadlines by which they must complete. -// Deadlines are enforced by an "actor" that persists for the lifetime of the -// client object: -// -// +----------------+ -// | | -// | check_deadline |<---+ -// | | | -// +----------------+ | async_wait() -// | | -// +---------+ -// -// If the deadline actor determines that the deadline has expired, the socket -// is closed and any outstanding operations are consequently cancelled. -// -// Connection establishment involves trying each endpoint in turn until a -// connection is successful, or the available endpoints are exhausted. If the -// deadline actor closes the socket, the connect actor is woken up and moves to -// the next endpoint. -// -// +---------------+ -// | | -// | start_connect |<---+ -// | | | -// +---------------+ | -// | | -// async_- | +----------------+ -// connect() | | | -// +--->| handle_connect | -// | | -// +----------------+ -// : -// Once a connection is : -// made, the connect : -// actor forks in two - : -// : -// an actor for reading : and an actor for -// inbound messages: : sending heartbeats: -// : -// +------------+ : +-------------+ -// | |<- - - - -+- - - - ->| | -// | start_read | | start_write |<---+ -// | |<---+ | | | -// +------------+ | +-------------+ | async_wait() -// | | | | -// async_- | +-------------+ async_- | +--------------+ -// read_- | | | write() | | | -// until() +--->| handle_read | +--->| handle_write | -// | | | | -// +-------------+ +--------------+ -// -// The input actor reads messages from the socket, where messages are delimited -// by the newline character. The deadline for a complete message is 30 seconds. -// -// The heartbeat actor sends a heartbeat (a message that consists of a single -// newline character) every 10 seconds. In this example, no deadline is applied -// to message sending. -// -class client -{ -public: - client(asio::io_context& io_context) - : stopped_(false), - socket_(io_context), - deadline_(io_context), - heartbeat_timer_(io_context) - { - } - - // Called by the user of the client class to initiate the connection process. - // The endpoints will have been obtained using a tcp::resolver. - void start(tcp::resolver::results_type endpoints) - { - // Start the connect actor. - endpoints_ = endpoints; - start_connect(endpoints_.begin()); - - // Start the deadline actor. You will note that we're not setting any - // particular deadline here. Instead, the connect and input actors will - // update the deadline prior to each asynchronous operation. - deadline_.async_wait(boost::bind(&client::check_deadline, this)); - } - - // This function terminates all the actors to shut down the connection. It - // may be called by the user of the client class, or by the class itself in - // response to graceful termination or an unrecoverable error. - void stop() - { - stopped_ = true; - asio::error_code ignored_ec; - socket_.close(ignored_ec); - deadline_.cancel(); - heartbeat_timer_.cancel(); - } - -private: - void start_connect(tcp::resolver::results_type::iterator endpoint_iter) - { - if (endpoint_iter != endpoints_.end()) - { - std::cout << "Trying " << endpoint_iter->endpoint() << "...\n"; - - // Set a deadline for the connect operation. - deadline_.expires_after(asio::chrono::seconds(60)); - - // Start the asynchronous connect operation. - socket_.async_connect(endpoint_iter->endpoint(), - boost::bind(&client::handle_connect, this, - boost::placeholders::_1, endpoint_iter)); - } - else - { - // There are no more endpoints to try. Shut down the client. - stop(); - } - } - - void handle_connect(const asio::error_code& ec, - tcp::resolver::results_type::iterator endpoint_iter) - { - if (stopped_) - return; - - // The async_connect() function automatically opens the socket at the start - // of the asynchronous operation. If the socket is closed at this time then - // the timeout handler must have run first. - if (!socket_.is_open()) - { - std::cout << "Connect timed out\n"; - - // Try the next available endpoint. - start_connect(++endpoint_iter); - } - - // Check if the connect operation failed before the deadline expired. - else if (ec) - { - std::cout << "Connect error: " << ec.message() << "\n"; - - // We need to close the socket used in the previous connection attempt - // before starting a new one. - socket_.close(); - - // Try the next available endpoint. - start_connect(++endpoint_iter); - } - - // Otherwise we have successfully established a connection. - else - { - std::cout << "Connected to " << endpoint_iter->endpoint() << "\n"; - - // Start the input actor. - start_read(); - - // Start the heartbeat actor. - start_write(); - } - } - - void start_read() - { - // Set a deadline for the read operation. - deadline_.expires_after(asio::chrono::seconds(30)); - - // Start an asynchronous operation to read a newline-delimited message. - asio::async_read_until(socket_, - asio::dynamic_buffer(input_buffer_), '\n', - boost::bind(&client::handle_read, this, - boost::placeholders::_1, boost::placeholders::_2)); - } - - void handle_read(const asio::error_code& ec, std::size_t n) - { - if (stopped_) - return; - - if (!ec) - { - // Extract the newline-delimited message from the buffer. - std::string line(input_buffer_.substr(0, n - 1)); - input_buffer_.erase(0, n); - - // Empty messages are heartbeats and so ignored. - if (!line.empty()) - { - std::cout << "Received: " << line << "\n"; - } - - start_read(); - } - else - { - std::cout << "Error on receive: " << ec.message() << "\n"; - - stop(); - } - } - - void start_write() - { - if (stopped_) - return; - - // Start an asynchronous operation to send a heartbeat message. - asio::async_write(socket_, asio::buffer("\n", 1), - boost::bind(&client::handle_write, this, boost::placeholders::_1)); - } - - void handle_write(const asio::error_code& ec) - { - if (stopped_) - return; - - if (!ec) - { - // Wait 10 seconds before sending the next heartbeat. - heartbeat_timer_.expires_after(asio::chrono::seconds(10)); - heartbeat_timer_.async_wait(boost::bind(&client::start_write, this)); - } - else - { - std::cout << "Error on heartbeat: " << ec.message() << "\n"; - - stop(); - } - } - - void check_deadline() - { - if (stopped_) - return; - - // Check whether the deadline has passed. We compare the deadline against - // the current time since a new asynchronous operation may have moved the - // deadline before this actor had a chance to run. - if (deadline_.expiry() <= steady_timer::clock_type::now()) - { - // The deadline has passed. The socket is closed so that any outstanding - // asynchronous operations are cancelled. - socket_.close(); - - // There is no longer an active deadline. The expiry is set to the - // maximum time point so that the actor takes no action until a new - // deadline is set. - deadline_.expires_at(steady_timer::time_point::max()); - } - - // Put the actor back to sleep. - deadline_.async_wait(boost::bind(&client::check_deadline, this)); - } - -private: - bool stopped_; - tcp::resolver::results_type endpoints_; - tcp::socket socket_; - std::string input_buffer_; - steady_timer deadline_; - steady_timer heartbeat_timer_; -}; - -int main(int argc, char* argv[]) -{ - try - { - if (argc != 3) - { - std::cerr << "Usage: client \n"; - return 1; - } - - asio::io_context io_context; - tcp::resolver r(io_context); - client c(io_context); - - c.start(r.resolve(argv[1], argv[2])); - - io_context.run(); - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - } - - return 0; -} diff --git a/asio/src/examples/cpp03/timeouts/blocking_tcp_client.cpp b/asio/src/examples/cpp03/timeouts/blocking_tcp_client.cpp deleted file mode 100644 index 4493ba5cf6..0000000000 --- a/asio/src/examples/cpp03/timeouts/blocking_tcp_client.cpp +++ /dev/null @@ -1,191 +0,0 @@ -// -// blocking_tcp_client.cpp -// ~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include "asio/buffer.hpp" -#include "asio/connect.hpp" -#include "asio/io_context.hpp" -#include "asio/ip/tcp.hpp" -#include "asio/read_until.hpp" -#include "asio/system_error.hpp" -#include "asio/write.hpp" -#include -#include -#include -#include -#include - -using asio::ip::tcp; -using boost::lambda::bind; -using boost::lambda::var; -using boost::lambda::_1; -using boost::lambda::_2; - -//---------------------------------------------------------------------- - -// -// This class manages socket timeouts by running the io_context using the timed -// io_context::run_for() member function. Each asynchronous operation is given -// a timeout within which it must complete. The socket operations themselves -// use boost::lambda function objects as completion handlers. For a given -// socket operation, the client object runs the io_context to block thread -// execution until the operation completes or the timeout is reached. If the -// io_context::run_for() function times out, the socket is closed and the -// outstanding asynchronous operation is cancelled. -// -class client -{ -public: - client() - : socket_(io_context_) - { - } - - void connect(const std::string& host, const std::string& service, - asio::chrono::steady_clock::duration timeout) - { - // Resolve the host name and service to a list of endpoints. - tcp::resolver::results_type endpoints = - tcp::resolver(io_context_).resolve(host, service); - - // Start the asynchronous operation itself. The boost::lambda function - // object is used as a callback and will update the ec variable when the - // operation completes. The blocking_udp_client.cpp example shows how you - // can use boost::bind rather than boost::lambda. - asio::error_code ec; - asio::async_connect(socket_, endpoints, var(ec) = _1); - - // Run the operation until it completes, or until the timeout. - run(timeout); - - // Determine whether a connection was successfully established. - if (ec) - throw asio::system_error(ec); - } - - std::string read_line(asio::chrono::steady_clock::duration timeout) - { - // Start the asynchronous operation. The boost::lambda function object is - // used as a callback and will update the ec variable when the operation - // completes. The blocking_udp_client.cpp example shows how you can use - // boost::bind rather than boost::lambda. - asio::error_code ec; - std::size_t n = 0; - asio::async_read_until(socket_, - asio::dynamic_buffer(input_buffer_), - '\n', (var(ec) = _1, var(n) = _2)); - - // Run the operation until it completes, or until the timeout. - run(timeout); - - // Determine whether the read completed successfully. - if (ec) - throw asio::system_error(ec); - - std::string line(input_buffer_.substr(0, n - 1)); - input_buffer_.erase(0, n); - return line; - } - - void write_line(const std::string& line, - asio::chrono::steady_clock::duration timeout) - { - std::string data = line + "\n"; - - // Start the asynchronous operation. The boost::lambda function object is - // used as a callback and will update the ec variable when the operation - // completes. The blocking_udp_client.cpp example shows how you can use - // boost::bind rather than boost::lambda. - asio::error_code ec; - asio::async_write(socket_, asio::buffer(data), var(ec) = _1); - - // Run the operation until it completes, or until the timeout. - run(timeout); - - // Determine whether the read completed successfully. - if (ec) - throw asio::system_error(ec); - } - -private: - void run(asio::chrono::steady_clock::duration timeout) - { - // Restart the io_context, as it may have been left in the "stopped" state - // by a previous operation. - io_context_.restart(); - - // Block until the asynchronous operation has completed, or timed out. If - // the pending asynchronous operation is a composed operation, the deadline - // applies to the entire operation, rather than individual operations on - // the socket. - io_context_.run_for(timeout); - - // If the asynchronous operation completed successfully then the io_context - // would have been stopped due to running out of work. If it was not - // stopped, then the io_context::run_for call must have timed out. - if (!io_context_.stopped()) - { - // Close the socket to cancel the outstanding asynchronous operation. - socket_.close(); - - // Run the io_context again until the operation completes. - io_context_.run(); - } - } - - asio::io_context io_context_; - tcp::socket socket_; - std::string input_buffer_; -}; - -//---------------------------------------------------------------------- - -int main(int argc, char* argv[]) -{ - try - { - if (argc != 4) - { - std::cerr << "Usage: blocking_tcp_client \n"; - return 1; - } - - client c; - c.connect(argv[1], argv[2], asio::chrono::seconds(10)); - - asio::chrono::steady_clock::time_point time_sent = - asio::chrono::steady_clock::now(); - - c.write_line(argv[3], asio::chrono::seconds(10)); - - for (;;) - { - std::string line = c.read_line(asio::chrono::seconds(10)); - - // Keep going until we get back the line that was sent. - if (line == argv[3]) - break; - } - - asio::chrono::steady_clock::time_point time_received = - asio::chrono::steady_clock::now(); - - std::cout << "Round trip time: "; - std::cout << asio::chrono::duration_cast< - asio::chrono::microseconds>( - time_received - time_sent).count(); - std::cout << " microseconds\n"; - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - } - - return 0; -} diff --git a/asio/src/examples/cpp03/timeouts/blocking_token_tcp_client.cpp b/asio/src/examples/cpp03/timeouts/blocking_token_tcp_client.cpp deleted file mode 100644 index f422a838b2..0000000000 --- a/asio/src/examples/cpp03/timeouts/blocking_token_tcp_client.cpp +++ /dev/null @@ -1,201 +0,0 @@ -// -// blocking_token_tcp_client.cpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include "asio/connect.hpp" -#include "asio/io_context.hpp" -#include "asio/ip/tcp.hpp" -#include "asio/read_until.hpp" -#include "asio/streambuf.hpp" -#include "asio/system_error.hpp" -#include "asio/write.hpp" -#include -#include -#include -#include - -using asio::ip::tcp; - -// We will use our sockets only with an io_context. -typedef asio::basic_stream_socket tcp_socket; - -//---------------------------------------------------------------------- - -// A custom completion token that makes asynchronous operations behave as -// though they are blocking calls with a timeout. -struct close_after -{ - close_after(asio::chrono::steady_clock::duration t, tcp_socket& s) - : timeout_(t), socket_(s) - { - } - - // The maximum time to wait for an asynchronous operation to complete. - asio::chrono::steady_clock::duration timeout_; - - // The socket to be closed if the operation does not complete in time. - tcp_socket& socket_; -}; - -namespace asio { - -// The async_result template is specialised to allow the close_after token to -// be used with asynchronous operations that have a completion signature of -// void(error_code, T). Generalising this for all completion signature forms is -// left as an exercise for the reader. -template -class async_result -{ -public: - // An asynchronous operation's initiating function automatically creates an - // completion_handler_type object from the token. This function object is - // then called on completion of the asynchronous operation. - class completion_handler_type - { - public: - completion_handler_type(const close_after& token) - : token_(token) - { - } - - void operator()(asio::error_code ec, T t) - { - *ec_ = ec; - *t_ = t; - } - - private: - friend class async_result; - close_after token_; - asio::error_code* ec_; - T* t_; - }; - - // The async_result constructor associates the completion handler object with - // the result of the initiating function. - explicit async_result(completion_handler_type& h) - : timeout_(h.token_.timeout_), - socket_(h.token_.socket_) - { - h.ec_ = &ec_; - h.t_ = &t_; - } - - // The return_type typedef determines the result type of the asynchronous - // operation's initiating function. - typedef T return_type; - - // The get() function is used to obtain the result of the asynchronous - // operation's initiating function. For the close_after completion token, we - // use this function to run the io_context until the operation is complete. - return_type get() - { - asio::io_context& io_context = asio::query( - socket_.get_executor(), asio::execution::context); - - // Restart the io_context, as it may have been left in the "stopped" state - // by a previous operation. - io_context.restart(); - - // Block until the asynchronous operation has completed, or timed out. If - // the pending asynchronous operation is a composed operation, the deadline - // applies to the entire operation, rather than individual operations on - // the socket. - io_context.run_for(timeout_); - - // If the asynchronous operation completed successfully then the io_context - // would have been stopped due to running out of work. If it was not - // stopped, then the io_context::run_for call must have timed out and the - // operation is still incomplete. - if (!io_context.stopped()) - { - // Close the socket to cancel the outstanding asynchronous operation. - socket_.close(); - - // Run the io_context again until the operation completes. - io_context.run(); - } - - // If the operation failed, throw an exception. Otherwise return the result. - return ec_ ? throw asio::system_error(ec_) : t_; - } - -private: - asio::chrono::steady_clock::duration timeout_; - tcp_socket& socket_; - asio::error_code ec_; - T t_; -}; - -} // namespace asio - -//---------------------------------------------------------------------- - -int main(int argc, char* argv[]) -{ - try - { - if (argc != 4) - { - std::cerr << "Usage: blocking_tcp_client \n"; - return 1; - } - - asio::io_context io_context; - - // Resolve the host name and service to a list of endpoints. - tcp::resolver::results_type endpoints = - tcp::resolver(io_context).resolve(argv[1], argv[2]); - - tcp_socket socket(io_context); - - // Run an asynchronous connect operation with a timeout. - asio::async_connect(socket, endpoints, - close_after(asio::chrono::seconds(10), socket)); - - asio::chrono::steady_clock::time_point time_sent = - asio::chrono::steady_clock::now(); - - // Run an asynchronous write operation with a timeout. - std::string msg = argv[3] + std::string("\n"); - asio::async_write(socket, asio::buffer(msg), - close_after(asio::chrono::seconds(10), socket)); - - for (std::string input_buffer;;) - { - // Run an asynchronous read operation with a timeout. - std::size_t n = asio::async_read_until(socket, - asio::dynamic_buffer(input_buffer), '\n', - close_after(asio::chrono::seconds(10), socket)); - - std::string line(input_buffer.substr(0, n - 1)); - input_buffer.erase(0, n); - - // Keep going until we get back the line that was sent. - if (line == argv[3]) - break; - } - - asio::chrono::steady_clock::time_point time_received = - asio::chrono::steady_clock::now(); - - std::cout << "Round trip time: "; - std::cout << asio::chrono::duration_cast< - asio::chrono::microseconds>( - time_received - time_sent).count(); - std::cout << " microseconds\n"; - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - } - - return 0; -} diff --git a/asio/src/examples/cpp03/timeouts/blocking_udp_client.cpp b/asio/src/examples/cpp03/timeouts/blocking_udp_client.cpp deleted file mode 100644 index 5c8e2f5767..0000000000 --- a/asio/src/examples/cpp03/timeouts/blocking_udp_client.cpp +++ /dev/null @@ -1,154 +0,0 @@ -// -// blocking_udp_client.cpp -// ~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include "asio/buffer.hpp" -#include "asio/io_context.hpp" -#include "asio/ip/udp.hpp" -#include -#include -#include - -using asio::ip::udp; - -//---------------------------------------------------------------------- - -// -// This class manages socket timeouts by running the io_context using the timed -// io_context::run_for() member function. Each asynchronous operation is given -// a timeout within which it must complete. The socket operations themselves -// use boost::bind to specify the completion handler: -// -// +---------------+ -// | | -// | receive | -// | | -// +---------------+ -// | -// async_- | +----------------+ -// receive() | | | -// +--->| handle_receive | -// | | -// +----------------+ -// -// For a given socket operation, the client object runs the io_context to block -// thread execution until the operation completes or the timeout is reached. If -// the io_context::run_for() function times out, the socket is closed and the -// outstanding asynchronous operation is cancelled. -// -class client -{ -public: - client(const udp::endpoint& listen_endpoint) - : socket_(io_context_, listen_endpoint) - { - } - - std::size_t receive(const asio::mutable_buffer& buffer, - asio::chrono::steady_clock::duration timeout, - asio::error_code& ec) - { - // Start the asynchronous operation. The handle_receive function used as a - // callback will update the ec and length variables. - std::size_t length = 0; - socket_.async_receive(asio::buffer(buffer), - boost::bind(&client::handle_receive, - boost::placeholders::_1, boost::placeholders::_2, &ec, &length)); - - // Run the operation until it completes, or until the timeout. - run(timeout); - - return length; - } - -private: - void run(asio::chrono::steady_clock::duration timeout) - { - // Restart the io_context, as it may have been left in the "stopped" state - // by a previous operation. - io_context_.restart(); - - // Block until the asynchronous operation has completed, or timed out. If - // the pending asynchronous operation is a composed operation, the deadline - // applies to the entire operation, rather than individual operations on - // the socket. - io_context_.run_for(timeout); - - // If the asynchronous operation completed successfully then the io_context - // would have been stopped due to running out of work. If it was not - // stopped, then the io_context::run_for call must have timed out. - if (!io_context_.stopped()) - { - // Cancel the outstanding asynchronous operation. - socket_.cancel(); - - // Run the io_context again until the operation completes. - io_context_.run(); - } - } - - static void handle_receive( - const asio::error_code& ec, std::size_t length, - asio::error_code* out_ec, std::size_t* out_length) - { - *out_ec = ec; - *out_length = length; - } - -private: - asio::io_context io_context_; - udp::socket socket_; -}; - -//---------------------------------------------------------------------- - -int main(int argc, char* argv[]) -{ - try - { - using namespace std; // For atoi. - - if (argc != 3) - { - std::cerr << "Usage: blocking_udp_client \n"; - return 1; - } - - udp::endpoint listen_endpoint( - asio::ip::make_address(argv[1]), - std::atoi(argv[2])); - - client c(listen_endpoint); - - for (;;) - { - char data[1024]; - asio::error_code ec; - std::size_t n = c.receive(asio::buffer(data), - asio::chrono::seconds(10), ec); - - if (ec) - { - std::cout << "Receive error: " << ec.message() << "\n"; - } - else - { - std::cout << "Received: "; - std::cout.write(data, n); - std::cout << "\n"; - } - } - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - } - - return 0; -} diff --git a/asio/src/examples/cpp03/timeouts/server.cpp b/asio/src/examples/cpp03/timeouts/server.cpp deleted file mode 100644 index 8dc957e260..0000000000 --- a/asio/src/examples/cpp03/timeouts/server.cpp +++ /dev/null @@ -1,433 +0,0 @@ -// -// server.cpp -// ~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "asio/buffer.hpp" -#include "asio/io_context.hpp" -#include "asio/ip/tcp.hpp" -#include "asio/ip/udp.hpp" -#include "asio/read_until.hpp" -#include "asio/steady_timer.hpp" -#include "asio/write.hpp" - -using asio::steady_timer; -using asio::ip::tcp; -using asio::ip::udp; - -//---------------------------------------------------------------------- - -class subscriber -{ -public: - virtual ~subscriber() {} - virtual void deliver(const std::string& msg) = 0; -}; - -typedef boost::shared_ptr subscriber_ptr; - -//---------------------------------------------------------------------- - -class channel -{ -public: - void join(subscriber_ptr subscriber) - { - subscribers_.insert(subscriber); - } - - void leave(subscriber_ptr subscriber) - { - subscribers_.erase(subscriber); - } - - void deliver(const std::string& msg) - { - std::for_each(subscribers_.begin(), subscribers_.end(), - boost::bind(&subscriber::deliver, - boost::placeholders::_1, boost::ref(msg))); - } - -private: - std::set subscribers_; -}; - -//---------------------------------------------------------------------- - -// -// This class manages socket timeouts by applying the concept of a deadline. -// Some asynchronous operations are given deadlines by which they must complete. -// Deadlines are enforced by two "actors" that persist for the lifetime of the -// session object, one for input and one for output: -// -// +----------------+ +----------------+ -// | | | | -// | check_deadline |<---+ | check_deadline |<---+ -// | | | async_wait() | | | async_wait() -// +----------------+ | on input +----------------+ | on output -// | | deadline | | deadline -// +---------+ +---------+ -// -// If either deadline actor determines that the corresponding deadline has -// expired, the socket is closed and any outstanding operations are cancelled. -// -// The input actor reads messages from the socket, where messages are delimited -// by the newline character: -// -// +------------+ -// | | -// | start_read |<---+ -// | | | -// +------------+ | -// | | -// async_- | +-------------+ -// read_- | | | -// until() +--->| handle_read | -// | | -// +-------------+ -// -// The deadline for receiving a complete message is 30 seconds. If a non-empty -// message is received, it is delivered to all subscribers. If a heartbeat (a -// message that consists of a single newline character) is received, a heartbeat -// is enqueued for the client, provided there are no other messages waiting to -// be sent. -// -// The output actor is responsible for sending messages to the client: -// -// +--------------+ -// | |<---------------------+ -// | await_output | | -// | |<---+ | -// +--------------+ | | -// | | | async_wait() | -// | +--------+ | -// V | -// +-------------+ +--------------+ -// | | async_write() | | -// | start_write |-------------->| handle_write | -// | | | | -// +-------------+ +--------------+ -// -// The output actor first waits for an output message to be enqueued. It does -// this by using a steady_timer as an asynchronous condition variable. The -// steady_timer will be signalled whenever the output queue is non-empty. -// -// Once a message is available, it is sent to the client. The deadline for -// sending a complete message is 30 seconds. After the message is successfully -// sent, the output actor again waits for the output queue to become non-empty. -// -class tcp_session - : public subscriber, - public boost::enable_shared_from_this -{ -public: - tcp_session(asio::io_context& io_context, channel& ch) - : channel_(ch), - socket_(io_context), - input_deadline_(io_context), - non_empty_output_queue_(io_context), - output_deadline_(io_context) - { - input_deadline_.expires_at(steady_timer::time_point::max()); - output_deadline_.expires_at(steady_timer::time_point::max()); - - // The non_empty_output_queue_ steady_timer is set to the maximum time - // point whenever the output queue is empty. This ensures that the output - // actor stays asleep until a message is put into the queue. - non_empty_output_queue_.expires_at(steady_timer::time_point::max()); - } - - tcp::socket& socket() - { - return socket_; - } - - // Called by the server object to initiate the four actors. - void start() - { - channel_.join(shared_from_this()); - - start_read(); - - input_deadline_.async_wait( - boost::bind(&tcp_session::check_deadline, - shared_from_this(), &input_deadline_)); - - await_output(); - - output_deadline_.async_wait( - boost::bind(&tcp_session::check_deadline, - shared_from_this(), &output_deadline_)); - } - -private: - void stop() - { - channel_.leave(shared_from_this()); - - asio::error_code ignored_ec; - socket_.close(ignored_ec); - input_deadline_.cancel(); - non_empty_output_queue_.cancel(); - output_deadline_.cancel(); - } - - bool stopped() const - { - return !socket_.is_open(); - } - - void deliver(const std::string& msg) - { - output_queue_.push_back(msg + "\n"); - - // Signal that the output queue contains messages. Modifying the expiry - // will wake the output actor, if it is waiting on the timer. - non_empty_output_queue_.expires_at(steady_timer::time_point::min()); - } - - void start_read() - { - // Set a deadline for the read operation. - input_deadline_.expires_after(asio::chrono::seconds(30)); - - // Start an asynchronous operation to read a newline-delimited message. - asio::async_read_until(socket_, - asio::dynamic_buffer(input_buffer_), '\n', - boost::bind(&tcp_session::handle_read, shared_from_this(), - boost::placeholders::_1, boost::placeholders::_2)); - } - - void handle_read(const asio::error_code& ec, std::size_t n) - { - if (stopped()) - return; - - if (!ec) - { - // Extract the newline-delimited message from the buffer. - std::string msg(input_buffer_.substr(0, n - 1)); - input_buffer_.erase(0, n); - - if (!msg.empty()) - { - channel_.deliver(msg); - } - else - { - // We received a heartbeat message from the client. If there's nothing - // else being sent or ready to be sent, send a heartbeat right back. - if (output_queue_.empty()) - { - output_queue_.push_back("\n"); - - // Signal that the output queue contains messages. Modifying the - // expiry will wake the output actor, if it is waiting on the timer. - non_empty_output_queue_.expires_at(steady_timer::time_point::min()); - } - } - - start_read(); - } - else - { - stop(); - } - } - - void await_output() - { - if (stopped()) - return; - - if (output_queue_.empty()) - { - // There are no messages that are ready to be sent. The actor goes to - // sleep by waiting on the non_empty_output_queue_ timer. When a new - // message is added, the timer will be modified and the actor will wake. - non_empty_output_queue_.expires_at(steady_timer::time_point::max()); - non_empty_output_queue_.async_wait( - boost::bind(&tcp_session::await_output, shared_from_this())); - } - else - { - start_write(); - } - } - - void start_write() - { - // Set a deadline for the write operation. - output_deadline_.expires_after(asio::chrono::seconds(30)); - - // Start an asynchronous operation to send a message. - asio::async_write(socket_, - asio::buffer(output_queue_.front()), - boost::bind(&tcp_session::handle_write, - shared_from_this(), boost::placeholders::_1)); - } - - void handle_write(const asio::error_code& ec) - { - if (stopped()) - return; - - if (!ec) - { - output_queue_.pop_front(); - - await_output(); - } - else - { - stop(); - } - } - - void check_deadline(steady_timer* deadline) - { - if (stopped()) - return; - - // Check whether the deadline has passed. We compare the deadline against - // the current time since a new asynchronous operation may have moved the - // deadline before this actor had a chance to run. - if (deadline->expiry() <= steady_timer::clock_type::now()) - { - // The deadline has passed. Stop the session. The other actors will - // terminate as soon as possible. - stop(); - } - else - { - // Put the actor back to sleep. - deadline->async_wait( - boost::bind(&tcp_session::check_deadline, - shared_from_this(), deadline)); - } - } - - channel& channel_; - tcp::socket socket_; - std::string input_buffer_; - steady_timer input_deadline_; - std::deque output_queue_; - steady_timer non_empty_output_queue_; - steady_timer output_deadline_; -}; - -typedef boost::shared_ptr tcp_session_ptr; - -//---------------------------------------------------------------------- - -class udp_broadcaster - : public subscriber -{ -public: - udp_broadcaster(asio::io_context& io_context, - const udp::endpoint& broadcast_endpoint) - : socket_(io_context) - { - socket_.connect(broadcast_endpoint); - socket_.set_option(udp::socket::broadcast(true)); - } - -private: - void deliver(const std::string& msg) - { - asio::error_code ignored_ec; - socket_.send(asio::buffer(msg), 0, ignored_ec); - } - - udp::socket socket_; -}; - -//---------------------------------------------------------------------- - -class server -{ -public: - server(asio::io_context& io_context, - const tcp::endpoint& listen_endpoint, - const udp::endpoint& broadcast_endpoint) - : io_context_(io_context), - acceptor_(io_context, listen_endpoint) - { - subscriber_ptr bc(new udp_broadcaster(io_context_, broadcast_endpoint)); - channel_.join(bc); - - start_accept(); - } - - void start_accept() - { - tcp_session_ptr new_session(new tcp_session(io_context_, channel_)); - - acceptor_.async_accept(new_session->socket(), - boost::bind(&server::handle_accept, - this, new_session, boost::placeholders::_1)); - } - - void handle_accept(tcp_session_ptr session, - const asio::error_code& ec) - { - if (!ec) - { - session->start(); - } - - start_accept(); - } - -private: - asio::io_context& io_context_; - tcp::acceptor acceptor_; - channel channel_; -}; - -//---------------------------------------------------------------------- - -int main(int argc, char* argv[]) -{ - try - { - using namespace std; // For atoi. - - if (argc != 4) - { - std::cerr << "Usage: server \n"; - return 1; - } - - asio::io_context io_context; - - tcp::endpoint listen_endpoint(tcp::v4(), atoi(argv[1])); - - udp::endpoint broadcast_endpoint( - asio::ip::make_address(argv[2]), atoi(argv[3])); - - server s(io_context, listen_endpoint, broadcast_endpoint); - - io_context.run(); - } - catch (std::exception& e) - { - std::cerr << "Exception: " << e.what() << "\n"; - } - - return 0; -} diff --git a/asio/src/examples/cpp03/timers/.gitignore b/asio/src/examples/cpp03/timers/.gitignore deleted file mode 100644 index a3fe695226..0000000000 --- a/asio/src/examples/cpp03/timers/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -.deps -.dirstamp -*.o -*.obj -*.exe -*timer -*.ilk -*.manifest -*.pdb -*.tds diff --git a/asio/src/examples/cpp03/timers/time_t_timer.cpp b/asio/src/examples/cpp03/timers/time_t_timer.cpp deleted file mode 100644 index c760623d0c..0000000000 --- a/asio/src/examples/cpp03/timers/time_t_timer.cpp +++ /dev/null @@ -1,106 +0,0 @@ -// -// time_t_timer.cpp -// ~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#include -#include -#include - -// A custom implementation of the Clock concept from the standard C++ library. -struct time_t_clock -{ - // The duration type. - typedef asio::chrono::steady_clock::duration duration; - - // The duration's underlying arithmetic representation. - typedef duration::rep rep; - - // The ratio representing the duration's tick period. - typedef duration::period period; - - // An absolute time point represented using the clock. - typedef asio::chrono::time_point time_point; - - // The clock is not monotonically increasing. - static const bool is_steady = false; - - // Get the current time. - static time_point now() - { - return time_point() + asio::chrono::seconds(std::time(0)); - } -}; - -// The asio::basic_waitable_timer template accepts an optional WaitTraits -// template parameter. The underlying time_t clock has one-second granularity, -// so these traits may be customised to reduce the latency between the clock -// ticking over and a wait operation's completion. When the timeout is near -// (less than one second away) we poll the clock more frequently to detect the -// time change closer to when it occurs. The user can select the appropriate -// trade off between accuracy and the increased CPU cost of polling. In extreme -// cases, a zero duration may be returned to make the timers as accurate as -// possible, albeit with 100% CPU usage. -struct time_t_wait_traits -{ - // Determine how long until the clock should be next polled to determine - // whether the duration has elapsed. - static time_t_clock::duration to_wait_duration( - const time_t_clock::duration& d) - { - if (d > asio::chrono::seconds(1)) - return d - asio::chrono::seconds(1); - else if (d > asio::chrono::seconds(0)) - return asio::chrono::milliseconds(10); - else - return asio::chrono::seconds(0); - } - - // Determine how long until the clock should be next polled to determine - // whether the absoluate time has been reached. - static time_t_clock::duration to_wait_duration( - const time_t_clock::time_point& t) - { - return to_wait_duration(t - time_t_clock::now()); - } -}; - -typedef asio::basic_waitable_timer< - time_t_clock, time_t_wait_traits> time_t_timer; - -void handle_timeout(const asio::error_code&) -{ - std::cout << "handle_timeout\n"; -} - -int main() -{ - try - { - asio::io_context io_context; - - time_t_timer timer(io_context); - - timer.expires_after(asio::chrono::seconds(5)); - std::cout << "Starting synchronous wait\n"; - timer.wait(); - std::cout << "Finished synchronous wait\n"; - - timer.expires_after(asio::chrono::seconds(5)); - std::cout << "Starting asynchronous wait\n"; - timer.async_wait(&handle_timeout); - io_context.run(); - std::cout << "Finished asynchronous wait\n"; - } - catch (std::exception& e) - { - std::cout << "Exception: " << e.what() << "\n"; - } - - return 0; -} diff --git a/asio/src/examples/cpp03/windows/.gitignore b/asio/src/examples/cpp03/windows/.gitignore deleted file mode 100644 index 180ba886e5..0000000000 --- a/asio/src/examples/cpp03/windows/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -.deps -.dirstamp -*.o -*.obj -*.exe -server -*.ilk -*.manifest -*.pdb -*.tds diff --git a/asio/src/examples/cpp11/Makefile.am b/asio/src/examples/cpp11/Makefile.am index d31ce02c7e..a132a469ff 100644 --- a/asio/src/examples/cpp11/Makefile.am +++ b/asio/src/examples/cpp11/Makefile.am @@ -32,8 +32,16 @@ noinst_PROGRAMS = \ files/async_file_copy \ futures/daytime_client \ handler_tracking/async_tcp_echo_server \ + http/client/async_client \ + http/client/sync_client \ http/server/http_server \ + http/server2/http_server \ + http/server3/http_server \ + http/server4/http_server \ + icmp/ping \ invocation/prioritised_handlers \ + iostreams/daytime_client \ + iostreams/daytime_server \ iostreams/http_client \ multicast/receiver \ multicast/sender \ @@ -51,6 +59,9 @@ noinst_PROGRAMS = \ parallel_group/wait_for_one \ parallel_group/wait_for_one_error \ parallel_group/wait_for_one_success \ + porthopper/client \ + porthopper/server \ + services/daytime_client \ socks4/sync_client \ timeouts/async_tcp_client \ timeouts/blocking_tcp_client \ @@ -58,10 +69,23 @@ noinst_PROGRAMS = \ timeouts/blocking_udp_client \ timeouts/server \ timers/time_t_timer \ + tutorial/timer1/timer \ + tutorial/timer2/timer \ + tutorial/timer3/timer \ + tutorial/timer4/timer \ + tutorial/timer5/timer \ + tutorial/daytime1/client \ + tutorial/daytime2/server \ + tutorial/daytime3/server \ + tutorial/daytime4/client \ + tutorial/daytime5/server \ + tutorial/daytime6/server \ + tutorial/daytime7/server \ type_erasure/type_erasure if !WINDOWS_TARGET noinst_PROGRAMS += \ + chat/posix_chat_client \ fork/daemon \ fork/process_per_connection \ local/connect_pair \ @@ -72,6 +96,11 @@ noinst_PROGRAMS += \ local/fd_passing_stream_client endif +if WINDOWS_TARGET +noinst_PROGRAMS += \ + windows/transmit_file +endif + if HAVE_OPENSSL noinst_PROGRAMS += \ ssl/client \ @@ -85,8 +114,51 @@ noinst_PROGRAMS += \ endif noinst_HEADERS = \ + chat/chat_message.hpp \ + handler_tracking/custom_tracking.hpp \ + http/server/connection.hpp \ + http/server/connection_manager.hpp \ + http/server/header.hpp \ + http/server/mime_types.hpp \ + http/server/reply.hpp \ + http/server/request.hpp \ + http/server/request_handler.hpp \ + http/server/request_parser.hpp \ + http/server/server.hpp \ + http/server2/connection.hpp \ + http/server2/io_context_pool.hpp \ + http/server2/header.hpp \ + http/server2/mime_types.hpp \ + http/server2/reply.hpp \ + http/server2/request.hpp \ + http/server2/request_handler.hpp \ + http/server2/request_parser.hpp \ + http/server2/server.hpp \ + http/server3/connection.hpp \ + http/server3/header.hpp \ + http/server3/mime_types.hpp \ + http/server3/reply.hpp \ + http/server3/request.hpp \ + http/server3/request_handler.hpp \ + http/server3/request_parser.hpp \ + http/server3/server.hpp \ + http/server4/file_handler.hpp \ + http/server4/header.hpp \ + http/server4/mime_types.hpp \ + http/server4/reply.hpp \ + http/server4/request.hpp \ + http/server4/request_parser.hpp \ + http/server4/server.hpp \ + icmp/icmp_header.hpp \ + icmp/ipv4_header.hpp \ + porthopper/protocol.hpp \ + services/basic_logger.hpp \ + services/logger.hpp \ + services/logger_service.hpp \ socks4/socks4.hpp \ - chat/chat_message.hpp + type_erasure/line_reader.hpp \ + type_erasure/stdin_line_reader.hpp \ + type_erasure/sleep.hpp AM_CXXFLAGS = -I$(srcdir)/../../../include @@ -112,6 +184,8 @@ files_blocking_file_copy_SOURCES = files/blocking_file_copy.cpp files_async_file_copy_SOURCES = files/async_file_copy.cpp futures_daytime_client_SOURCES = futures/daytime_client.cpp handler_tracking_async_tcp_echo_server_SOURCES = handler_tracking/async_tcp_echo_server.cpp +http_client_async_client_SOURCES = http/client/async_client.cpp +http_client_sync_client_SOURCES = http/client/sync_client.cpp http_server_http_server_SOURCES = \ http/server/connection.cpp \ http/server/connection_manager.cpp \ @@ -121,7 +195,34 @@ http_server_http_server_SOURCES = \ http/server/request_handler.cpp \ http/server/request_parser.cpp \ http/server/server.cpp +http_server2_http_server_SOURCES = \ + http/server2/connection.cpp \ + http/server2/io_context_pool.cpp \ + http/server2/main.cpp \ + http/server2/mime_types.cpp \ + http/server2/reply.cpp \ + http/server2/request_handler.cpp \ + http/server2/request_parser.cpp \ + http/server2/server.cpp +http_server3_http_server_SOURCES = \ + http/server3/connection.cpp \ + http/server3/main.cpp \ + http/server3/mime_types.cpp \ + http/server3/reply.cpp \ + http/server3/request_handler.cpp \ + http/server3/request_parser.cpp \ + http/server3/server.cpp +http_server4_http_server_SOURCES = \ + http/server4/file_handler.cpp \ + http/server4/main.cpp \ + http/server4/mime_types.cpp \ + http/server4/reply.cpp \ + http/server4/request_parser.cpp \ + http/server4/server.cpp +icmp_ping_SOURCES = icmp/ping.cpp invocation_prioritised_handlers_SOURCES = invocation/prioritised_handlers.cpp +iostreams_daytime_client_SOURCES = iostreams/daytime_client.cpp +iostreams_daytime_server_SOURCES = iostreams/daytime_server.cpp iostreams_http_client_SOURCES = iostreams/http_client.cpp multicast_receiver_SOURCES = multicast/receiver.cpp multicast_sender_SOURCES = multicast/sender.cpp @@ -139,6 +240,11 @@ parallel_group_wait_for_all_SOURCES = parallel_group/wait_for_all.cpp parallel_group_wait_for_one_SOURCES = parallel_group/wait_for_one.cpp parallel_group_wait_for_one_error_SOURCES = parallel_group/wait_for_one_error.cpp parallel_group_wait_for_one_success_SOURCES = parallel_group/wait_for_one_success.cpp +porthopper_client_SOURCES = porthopper/client.cpp +porthopper_server_SOURCES = porthopper/server.cpp +services_daytime_client_SOURCES = \ + services/daytime_client.cpp \ + services/logger_service.cpp socks4_sync_client_SOURCES = socks4/sync_client.cpp timeouts_async_tcp_client_SOURCES = timeouts/async_tcp_client.cpp timeouts_blocking_tcp_client_SOURCES = timeouts/blocking_tcp_client.cpp @@ -146,9 +252,22 @@ timeouts_blocking_token_tcp_client_SOURCES = timeouts/blocking_token_tcp_client. timeouts_blocking_udp_client_SOURCES = timeouts/blocking_udp_client.cpp timeouts_server_SOURCES = timeouts/server.cpp timers_time_t_timer_SOURCES = timers/time_t_timer.cpp +tutorial_timer1_timer_SOURCES = tutorial/timer1/timer.cpp +tutorial_timer2_timer_SOURCES = tutorial/timer2/timer.cpp +tutorial_timer3_timer_SOURCES = tutorial/timer3/timer.cpp +tutorial_timer4_timer_SOURCES = tutorial/timer4/timer.cpp +tutorial_timer5_timer_SOURCES = tutorial/timer5/timer.cpp +tutorial_daytime1_client_SOURCES = tutorial/daytime1/client.cpp +tutorial_daytime2_server_SOURCES = tutorial/daytime2/server.cpp +tutorial_daytime3_server_SOURCES = tutorial/daytime3/server.cpp +tutorial_daytime4_client_SOURCES = tutorial/daytime4/client.cpp +tutorial_daytime5_server_SOURCES = tutorial/daytime5/server.cpp +tutorial_daytime6_server_SOURCES = tutorial/daytime6/server.cpp +tutorial_daytime7_server_SOURCES = tutorial/daytime7/server.cpp type_erasure_type_erasure_SOURCES = type_erasure/main.cpp type_erasure/stdin_line_reader.cpp type_erasure/sleep.cpp if !WINDOWS_TARGET +chat_posix_chat_client_SOURCES = chat/posix_chat_client.cpp fork_daemon_SOURCES = fork/daemon.cpp fork_process_per_connection_SOURCES = fork/process_per_connection.cpp local_connect_pair_SOURCES = local/connect_pair.cpp @@ -159,6 +278,10 @@ local_fd_passing_stream_server_SOURCES = local/fd_passing_stream_server.cpp local_fd_passing_stream_client_SOURCES = local/fd_passing_stream_client.cpp endif +if WINDOWS_TARGET +windows_transmit_file_SOURCES = windows/transmit_file.cpp +endif + if HAVE_OPENSSL ssl_client_SOURCES = ssl/client.cpp ssl_server_SOURCES = ssl/server.cpp @@ -172,24 +295,14 @@ spawn_parallel_grep_LDADD = $(LDADD) -lboost_coroutine -lboost_context -lboost_t endif EXTRA_DIST = \ - handler_tracking/custom_tracking.hpp \ - http/server/connection.hpp \ - http/server/connection_manager.hpp \ - http/server/header.hpp \ - http/server/mime_types.hpp \ - http/server/reply.hpp \ - http/server/request.hpp \ - http/server/request_handler.hpp \ - http/server/request_parser.hpp \ - http/server/server.hpp \ + serialization/client.cpp \ + serialization/server.cpp \ + serialization/connection.hpp \ + serialization/stock.hpp \ ssl/README \ ssl/ca.pem \ ssl/server.pem \ - ssl/dh4096.pem \ - type_erasure/line_reader.hpp \ - type_erasure/stdin_line_reader.hpp \ - type_erasure/sleep.hpp - + ssl/dh4096.pem MAINTAINERCLEANFILES = \ $(srcdir)/Makefile.in diff --git a/asio/src/examples/cpp11/chat/posix_chat_client.cpp b/asio/src/examples/cpp11/chat/posix_chat_client.cpp new file mode 100644 index 0000000000..433caa289a --- /dev/null +++ b/asio/src/examples/cpp11/chat/posix_chat_client.cpp @@ -0,0 +1,198 @@ +// +// posix_chat_client.cpp +// ~~~~~~~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include +#include +#include +#include +#include "asio.hpp" +#include "chat_message.hpp" + +#if defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) + +using asio::ip::tcp; +namespace posix = asio::posix; + +class posix_chat_client +{ +public: + posix_chat_client(asio::io_context& io_context, + const tcp::resolver::results_type& endpoints) + : socket_(io_context), + input_(io_context, ::dup(STDIN_FILENO)), + output_(io_context, ::dup(STDOUT_FILENO)), + input_buffer_(chat_message::max_body_length) + { + do_connect(endpoints); + } + +private: + void do_connect(const tcp::resolver::results_type& endpoints) + { + asio::async_connect(socket_, endpoints, + [this](std::error_code ec, tcp::endpoint) + { + if (!ec) + { + do_read_header(); + do_read_input(); + } + }); + } + + void do_read_header() + { + asio::async_read(socket_, + asio::buffer(read_msg_.data(), chat_message::header_length), + [this](std::error_code ec, std::size_t /*length*/) + { + if (!ec && read_msg_.decode_header()) + { + do_read_body(); + } + else + { + close(); + } + }); + } + + void do_read_body() + { + asio::async_read(socket_, + asio::buffer(read_msg_.body(), read_msg_.body_length()), + [this](std::error_code ec, std::size_t /*length*/) + { + if (!ec) + { + do_write_output(); + } + else + { + close(); + } + }); + } + + void do_write_output() + { + // Write out the message we just received, terminated by a newline. + static char eol[] = { '\n' }; + std::array buffers = {{ + asio::buffer(read_msg_.body(), read_msg_.body_length()), + asio::buffer(eol) }}; + asio::async_write(output_, buffers, + [this](std::error_code ec, std::size_t /*length*/) + { + if (!ec) + { + do_read_header(); + } + else + { + close(); + } + }); + } + + void do_read_input() + { + // Read a line of input entered by the user. + asio::async_read_until(input_, input_buffer_, '\n', + [this](std::error_code ec, std::size_t length) + { + if (!ec) + { + // Write the message (minus the newline) to the server. + write_msg_.body_length(length - 1); + input_buffer_.sgetn(write_msg_.body(), length - 1); + input_buffer_.consume(1); // Remove newline from input. + write_msg_.encode_header(); + do_write_message(); + } + else if (ec == asio::error::not_found) + { + // Didn't get a newline. Send whatever we have. + write_msg_.body_length(input_buffer_.size()); + input_buffer_.sgetn(write_msg_.body(), input_buffer_.size()); + write_msg_.encode_header(); + do_write_message(); + } + else + { + close(); + } + }); + } + + void do_write_message() + { + asio::async_write(socket_, + asio::buffer(write_msg_.data(), write_msg_.length()), + [this](std::error_code ec, std::size_t /*length*/) + { + if (!ec) + { + do_read_input(); + } + else + { + close(); + } + }); + } + + void close() + { + // Cancel all outstanding asynchronous operations. + socket_.close(); + input_.close(); + output_.close(); + } + +private: + tcp::socket socket_; + posix::stream_descriptor input_; + posix::stream_descriptor output_; + chat_message read_msg_; + chat_message write_msg_; + asio::streambuf input_buffer_; +}; + +int main(int argc, char* argv[]) +{ + try + { + if (argc != 3) + { + std::cerr << "Usage: posix_chat_client \n"; + return 1; + } + + asio::io_context io_context; + + tcp::resolver resolver(io_context); + tcp::resolver::results_type endpoints = resolver.resolve(argv[1], argv[2]); + + posix_chat_client c(io_context, endpoints); + + io_context.run(); + } + catch (std::exception& e) + { + std::cerr << "Exception: " << e.what() << "\n"; + } + + return 0; +} + +#else // defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) +int main() {} +#endif // defined(ASIO_HAS_POSIX_STREAM_DESCRIPTOR) diff --git a/asio/src/examples/cpp11/echo/blocking_tcp_echo_server.cpp b/asio/src/examples/cpp11/echo/blocking_tcp_echo_server.cpp index a319da25a2..32fa914dfc 100644 --- a/asio/src/examples/cpp11/echo/blocking_tcp_echo_server.cpp +++ b/asio/src/examples/cpp11/echo/blocking_tcp_echo_server.cpp @@ -26,12 +26,12 @@ void session(tcp::socket sock) { char data[max_length]; - asio::error_code error; + std::error_code error; size_t length = sock.read_some(asio::buffer(data), error); if (error == asio::error::eof) break; // Connection closed cleanly by peer. else if (error) - throw asio::system_error(error); // Some other error. + throw std::system_error(error); // Some other error. asio::write(sock, asio::buffer(data, length)); } diff --git a/asio/src/examples/cpp11/files/blocking_file_copy.cpp b/asio/src/examples/cpp11/files/blocking_file_copy.cpp index 50e2cd41e1..f55a7880ce 100644 --- a/asio/src/examples/cpp11/files/blocking_file_copy.cpp +++ b/asio/src/examples/cpp11/files/blocking_file_copy.cpp @@ -34,7 +34,7 @@ int main(int argc, char* argv[]) | asio::stream_file::truncate); char data[4096]; - asio::error_code error; + std::error_code error; for (;;) { std::size_t n = from_file.read_some(asio::buffer(data), error); diff --git a/asio/src/examples/cpp11/handler_tracking/custom_tracking.hpp b/asio/src/examples/cpp11/handler_tracking/custom_tracking.hpp index c9114db202..84e0d43fb6 100644 --- a/asio/src/examples/cpp11/handler_tracking/custom_tracking.hpp +++ b/asio/src/examples/cpp11/handler_tracking/custom_tracking.hpp @@ -187,7 +187,7 @@ struct custom_tracking // Record a reactor-based operation that is associated with a handler. static void reactor_operation(const tracked_handler& h, - const char* op_name, const asio::error_code& ec) + const char* op_name, const std::error_code& ec) { std::printf( "Performed operation %s.%s for native_handle = %" PRIuMAX @@ -197,7 +197,7 @@ struct custom_tracking // Record a reactor-based operation that is associated with a handler. static void reactor_operation(const tracked_handler& h, - const char* op_name, const asio::error_code& ec, + const char* op_name, const std::error_code& ec, std::size_t bytes_transferred) { std::printf( diff --git a/asio/src/examples/cpp03/http/client/.gitignore b/asio/src/examples/cpp11/http/client/.gitignore similarity index 100% rename from asio/src/examples/cpp03/http/client/.gitignore rename to asio/src/examples/cpp11/http/client/.gitignore diff --git a/asio/src/examples/cpp03/http/client/async_client.cpp b/asio/src/examples/cpp11/http/client/async_client.cpp similarity index 86% rename from asio/src/examples/cpp03/http/client/async_client.cpp rename to asio/src/examples/cpp11/http/client/async_client.cpp index e9116fd26a..d1e4768f40 100644 --- a/asio/src/examples/cpp03/http/client/async_client.cpp +++ b/asio/src/examples/cpp11/http/client/async_client.cpp @@ -8,12 +8,12 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // +#include #include #include #include #include #include -#include using asio::ip::tcp; @@ -37,13 +37,13 @@ class client // Start an asynchronous resolve to translate the server and service names // into a list of endpoints. resolver_.async_resolve(server, "http", - boost::bind(&client::handle_resolve, this, + std::bind(&client::handle_resolve, this, asio::placeholders::error, asio::placeholders::results)); } private: - void handle_resolve(const asio::error_code& err, + void handle_resolve(const std::error_code& err, const tcp::resolver::results_type& endpoints) { if (!err) @@ -51,7 +51,7 @@ class client // Attempt a connection to each endpoint in the list until we // successfully establish a connection. asio::async_connect(socket_, endpoints, - boost::bind(&client::handle_connect, this, + std::bind(&client::handle_connect, this, asio::placeholders::error)); } else @@ -60,13 +60,13 @@ class client } } - void handle_connect(const asio::error_code& err) + void handle_connect(const std::error_code& err) { if (!err) { // The connection was successful. Send the request. asio::async_write(socket_, request_, - boost::bind(&client::handle_write_request, this, + std::bind(&client::handle_write_request, this, asio::placeholders::error)); } else @@ -75,7 +75,7 @@ class client } } - void handle_write_request(const asio::error_code& err) + void handle_write_request(const std::error_code& err) { if (!err) { @@ -83,7 +83,7 @@ class client // automatically grow to accommodate the entire line. The growth may be // limited by passing a maximum size to the streambuf constructor. asio::async_read_until(socket_, response_, "\r\n", - boost::bind(&client::handle_read_status_line, this, + std::bind(&client::handle_read_status_line, this, asio::placeholders::error)); } else @@ -92,7 +92,7 @@ class client } } - void handle_read_status_line(const asio::error_code& err) + void handle_read_status_line(const std::error_code& err) { if (!err) { @@ -118,7 +118,7 @@ class client // Read the response headers, which are terminated by a blank line. asio::async_read_until(socket_, response_, "\r\n\r\n", - boost::bind(&client::handle_read_headers, this, + std::bind(&client::handle_read_headers, this, asio::placeholders::error)); } else @@ -127,7 +127,7 @@ class client } } - void handle_read_headers(const asio::error_code& err) + void handle_read_headers(const std::error_code& err) { if (!err) { @@ -145,7 +145,7 @@ class client // Start reading remaining data until EOF. asio::async_read(socket_, response_, asio::transfer_at_least(1), - boost::bind(&client::handle_read_content, this, + std::bind(&client::handle_read_content, this, asio::placeholders::error)); } else @@ -154,7 +154,7 @@ class client } } - void handle_read_content(const asio::error_code& err) + void handle_read_content(const std::error_code& err) { if (!err) { @@ -164,7 +164,7 @@ class client // Continue reading remaining data until EOF. asio::async_read(socket_, response_, asio::transfer_at_least(1), - boost::bind(&client::handle_read_content, this, + std::bind(&client::handle_read_content, this, asio::placeholders::error)); } else if (err != asio::error::eof) diff --git a/asio/src/examples/cpp03/http/client/sync_client.cpp b/asio/src/examples/cpp11/http/client/sync_client.cpp similarity index 97% rename from asio/src/examples/cpp03/http/client/sync_client.cpp rename to asio/src/examples/cpp11/http/client/sync_client.cpp index d0ac47ddca..9166babd64 100644 --- a/asio/src/examples/cpp03/http/client/sync_client.cpp +++ b/asio/src/examples/cpp11/http/client/sync_client.cpp @@ -90,12 +90,12 @@ int main(int argc, char* argv[]) std::cout << &response; // Read until EOF, writing data to output as we go. - asio::error_code error; + std::error_code error; while (asio::read(socket, response, asio::transfer_at_least(1), error)) std::cout << &response; if (error != asio::error::eof) - throw asio::system_error(error); + throw std::system_error(error); } catch (std::exception& e) { diff --git a/asio/src/examples/cpp03/http/doc_root/data_1K.html b/asio/src/examples/cpp11/http/doc_root/data_1K.html similarity index 100% rename from asio/src/examples/cpp03/http/doc_root/data_1K.html rename to asio/src/examples/cpp11/http/doc_root/data_1K.html diff --git a/asio/src/examples/cpp03/http/doc_root/data_2K.html b/asio/src/examples/cpp11/http/doc_root/data_2K.html similarity index 100% rename from asio/src/examples/cpp03/http/doc_root/data_2K.html rename to asio/src/examples/cpp11/http/doc_root/data_2K.html diff --git a/asio/src/examples/cpp03/http/doc_root/data_4K.html b/asio/src/examples/cpp11/http/doc_root/data_4K.html similarity index 100% rename from asio/src/examples/cpp03/http/doc_root/data_4K.html rename to asio/src/examples/cpp11/http/doc_root/data_4K.html diff --git a/asio/src/examples/cpp03/http/doc_root/data_8K.html b/asio/src/examples/cpp11/http/doc_root/data_8K.html similarity index 100% rename from asio/src/examples/cpp03/http/doc_root/data_8K.html rename to asio/src/examples/cpp11/http/doc_root/data_8K.html diff --git a/asio/src/examples/cpp11/http/server/connection.cpp b/asio/src/examples/cpp11/http/server/connection.cpp index 82eb62a155..bc6de52bf2 100644 --- a/asio/src/examples/cpp11/http/server/connection.cpp +++ b/asio/src/examples/cpp11/http/server/connection.cpp @@ -10,7 +10,6 @@ #include "connection.hpp" #include -#include #include "connection_manager.hpp" #include "request_handler.hpp" @@ -78,7 +77,7 @@ void connection::do_write() if (!ec) { // Initiate graceful connection closure. - asio::error_code ignored_ec; + std::error_code ignored_ec; socket_.shutdown(asio::ip::tcp::socket::shutdown_both, ignored_ec); } diff --git a/asio/src/examples/cpp11/http/server/connection.hpp b/asio/src/examples/cpp11/http/server/connection.hpp index dfaa4dd5f3..d8681b9224 100644 --- a/asio/src/examples/cpp11/http/server/connection.hpp +++ b/asio/src/examples/cpp11/http/server/connection.hpp @@ -11,9 +11,9 @@ #ifndef HTTP_CONNECTION_HPP #define HTTP_CONNECTION_HPP +#include #include #include -#include #include "reply.hpp" #include "request.hpp" #include "request_handler.hpp" diff --git a/asio/src/examples/cpp03/chat/.gitignore b/asio/src/examples/cpp11/http/server2/.gitignore similarity index 100% rename from asio/src/examples/cpp03/chat/.gitignore rename to asio/src/examples/cpp11/http/server2/.gitignore diff --git a/asio/src/examples/cpp11/http/server2/connection.cpp b/asio/src/examples/cpp11/http/server2/connection.cpp new file mode 100644 index 0000000000..5ca139d372 --- /dev/null +++ b/asio/src/examples/cpp11/http/server2/connection.cpp @@ -0,0 +1,89 @@ +// +// connection.cpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include "connection.hpp" +#include +#include "request_handler.hpp" + +namespace http { +namespace server2 { + +connection::connection(asio::ip::tcp::socket socket, + request_handler& handler) + : socket_(std::move(socket)), + request_handler_(handler) +{ +} + +void connection::start() +{ + do_read(); +} + +void connection::do_read() +{ + auto self(shared_from_this()); + socket_.async_read_some(asio::buffer(buffer_), + [this, self](std::error_code ec, std::size_t bytes_transferred) + { + if (!ec) + { + request_parser::result_type result; + std::tie(result, std::ignore) = request_parser_.parse( + request_, buffer_.data(), buffer_.data() + bytes_transferred); + + if (result == request_parser::good) + { + request_handler_.handle_request(request_, reply_); + do_write(); + } + else if (result == request_parser::bad) + { + reply_ = reply::stock_reply(reply::bad_request); + do_write(); + } + else + { + do_read(); + } + } + + // If an error occurs then no new asynchronous operations are + // started. This means that all shared_ptr references to the + // connection object will disappear and the object will be + // destroyed automatically after this handler returns. The + // connection class's destructor closes the socket. + }); +} + +void connection::do_write() +{ + auto self(shared_from_this()); + asio::async_write(socket_, reply_.to_buffers(), + [this, self](std::error_code ec, std::size_t) + { + if (!ec) + { + // Initiate graceful connection closure. + std::error_code ignored_ec; + socket_.shutdown(asio::ip::tcp::socket::shutdown_both, + ignored_ec); + } + + // No new asynchronous operations are started. This means that + // all shared_ptr references to the connection object will + // disappear and the object will be destroyed automatically after + // this handler returns. The connection class's destructor closes + // the socket. + }); +} + +} // namespace server2 +} // namespace http diff --git a/asio/src/examples/cpp03/http/server2/connection.hpp b/asio/src/examples/cpp11/http/server2/connection.hpp similarity index 61% rename from asio/src/examples/cpp03/http/server2/connection.hpp rename to asio/src/examples/cpp11/http/server2/connection.hpp index 4646460830..90c8597946 100644 --- a/asio/src/examples/cpp03/http/server2/connection.hpp +++ b/asio/src/examples/cpp11/http/server2/connection.hpp @@ -12,10 +12,8 @@ #define HTTP_SERVER2_CONNECTION_HPP #include -#include -#include -#include -#include +#include +#include #include "reply.hpp" #include "request.hpp" #include "request_handler.hpp" @@ -26,27 +24,25 @@ namespace server2 { /// Represents a single connection from a client. class connection - : public boost::enable_shared_from_this, - private boost::noncopyable + : public std::enable_shared_from_this { public: - /// Construct a connection with the given io_context. - explicit connection(asio::io_context& io_context, - request_handler& handler); + connection(const connection&) = delete; + connection& operator=(const connection&) = delete; - /// Get the socket associated with the connection. - asio::ip::tcp::socket& socket(); + /// Construct a connection with the given socket. + explicit connection(asio::ip::tcp::socket socket, + request_handler& handler); /// Start the first asynchronous operation for the connection. void start(); private: - /// Handle completion of a read operation. - void handle_read(const asio::error_code& e, - std::size_t bytes_transferred); + /// Perform an asynchronous read operation. + void do_read(); - /// Handle completion of a write operation. - void handle_write(const asio::error_code& e); + /// Perform an asynchronous write operation. + void do_write(); /// Socket for the connection. asio::ip::tcp::socket socket_; @@ -55,7 +51,7 @@ class connection request_handler& request_handler_; /// Buffer for incoming data. - boost::array buffer_; + std::array buffer_; /// The incoming request. request request_; @@ -67,7 +63,7 @@ class connection reply reply_; }; -typedef boost::shared_ptr connection_ptr; +typedef std::shared_ptr connection_ptr; } // namespace server2 } // namespace http diff --git a/asio/src/examples/cpp03/http/server2/header.hpp b/asio/src/examples/cpp11/http/server2/header.hpp similarity index 100% rename from asio/src/examples/cpp03/http/server2/header.hpp rename to asio/src/examples/cpp11/http/server2/header.hpp diff --git a/asio/src/examples/cpp03/http/server2/io_context_pool.cpp b/asio/src/examples/cpp11/http/server2/io_context_pool.cpp similarity index 83% rename from asio/src/examples/cpp03/http/server2/io_context_pool.cpp rename to asio/src/examples/cpp11/http/server2/io_context_pool.cpp index 2f3592381f..895c4cc263 100644 --- a/asio/src/examples/cpp03/http/server2/io_context_pool.cpp +++ b/asio/src/examples/cpp11/http/server2/io_context_pool.cpp @@ -10,8 +10,7 @@ #include "server.hpp" #include -#include -#include +#include namespace http { namespace server2 { @@ -35,17 +34,13 @@ io_context_pool::io_context_pool(std::size_t pool_size) void io_context_pool::run() { // Create a pool of threads to run all of the io_contexts. - std::vector > threads; + std::vector threads; for (std::size_t i = 0; i < io_contexts_.size(); ++i) - { - boost::shared_ptr thread(new asio::thread( - boost::bind(&asio::io_context::run, io_contexts_[i]))); - threads.push_back(thread); - } + threads.emplace_back([this, i]{ io_contexts_[i]->run(); }); // Wait for all threads in the pool to exit. for (std::size_t i = 0; i < threads.size(); ++i) - threads[i]->join(); + threads[i].join(); } void io_context_pool::stop() diff --git a/asio/src/examples/cpp03/http/server2/io_context_pool.hpp b/asio/src/examples/cpp11/http/server2/io_context_pool.hpp similarity index 86% rename from asio/src/examples/cpp03/http/server2/io_context_pool.hpp rename to asio/src/examples/cpp11/http/server2/io_context_pool.hpp index 0f59be081c..d9473fac84 100644 --- a/asio/src/examples/cpp03/http/server2/io_context_pool.hpp +++ b/asio/src/examples/cpp11/http/server2/io_context_pool.hpp @@ -13,16 +13,14 @@ #include #include +#include #include -#include -#include namespace http { namespace server2 { /// A pool of io_context objects. class io_context_pool - : private boost::noncopyable { public: /// Construct the io_context pool. @@ -38,7 +36,10 @@ class io_context_pool asio::io_context& get_io_context(); private: - typedef boost::shared_ptr io_context_ptr; + io_context_pool(const io_context_pool&) = delete; + io_context_pool& operator=(const io_context_pool&) = delete; + + typedef std::shared_ptr io_context_ptr; typedef asio::executor_work_guard< asio::io_context::executor_type> io_context_work; diff --git a/asio/src/examples/cpp03/http/server2/main.cpp b/asio/src/examples/cpp11/http/server2/main.cpp similarity index 87% rename from asio/src/examples/cpp03/http/server2/main.cpp rename to asio/src/examples/cpp11/http/server2/main.cpp index e4788f0ab4..baa88d2a2b 100644 --- a/asio/src/examples/cpp03/http/server2/main.cpp +++ b/asio/src/examples/cpp11/http/server2/main.cpp @@ -11,8 +11,6 @@ #include #include #include -#include -#include #include "server.hpp" int main(int argc, char* argv[]) @@ -31,7 +29,7 @@ int main(int argc, char* argv[]) } // Initialise the server. - std::size_t num_threads = boost::lexical_cast(argv[3]); + std::size_t num_threads = std::stoi(argv[3]); http::server2::server s(argv[1], argv[2], argv[4], num_threads); // Run the server until stopped. diff --git a/asio/src/examples/cpp03/http/server2/mime_types.cpp b/asio/src/examples/cpp11/http/server2/mime_types.cpp similarity index 100% rename from asio/src/examples/cpp03/http/server2/mime_types.cpp rename to asio/src/examples/cpp11/http/server2/mime_types.cpp diff --git a/asio/src/examples/cpp03/http/server2/mime_types.hpp b/asio/src/examples/cpp11/http/server2/mime_types.hpp similarity index 100% rename from asio/src/examples/cpp03/http/server2/mime_types.hpp rename to asio/src/examples/cpp11/http/server2/mime_types.hpp diff --git a/asio/src/examples/cpp03/http/server2/reply.cpp b/asio/src/examples/cpp11/http/server2/reply.cpp similarity index 98% rename from asio/src/examples/cpp03/http/server2/reply.cpp rename to asio/src/examples/cpp11/http/server2/reply.cpp index 19787c5eff..39e3b2163d 100644 --- a/asio/src/examples/cpp03/http/server2/reply.cpp +++ b/asio/src/examples/cpp11/http/server2/reply.cpp @@ -10,7 +10,6 @@ #include "reply.hpp" #include -#include namespace http { namespace server2 { @@ -246,7 +245,7 @@ reply reply::stock_reply(reply::status_type status) rep.content = stock_replies::to_string(status); rep.headers.resize(2); rep.headers[0].name = "Content-Length"; - rep.headers[0].value = boost::lexical_cast(rep.content.size()); + rep.headers[0].value = std::to_string(rep.content.size()); rep.headers[1].name = "Content-Type"; rep.headers[1].value = "text/html"; return rep; diff --git a/asio/src/examples/cpp03/http/server2/reply.hpp b/asio/src/examples/cpp11/http/server2/reply.hpp similarity index 100% rename from asio/src/examples/cpp03/http/server2/reply.hpp rename to asio/src/examples/cpp11/http/server2/reply.hpp diff --git a/asio/src/examples/cpp03/http/server2/request.hpp b/asio/src/examples/cpp11/http/server2/request.hpp similarity index 100% rename from asio/src/examples/cpp03/http/server2/request.hpp rename to asio/src/examples/cpp11/http/server2/request.hpp diff --git a/asio/src/examples/cpp03/http/server2/request_handler.cpp b/asio/src/examples/cpp11/http/server2/request_handler.cpp similarity index 96% rename from asio/src/examples/cpp03/http/server2/request_handler.cpp rename to asio/src/examples/cpp11/http/server2/request_handler.cpp index 8fe23b54ee..db51f4a21f 100644 --- a/asio/src/examples/cpp03/http/server2/request_handler.cpp +++ b/asio/src/examples/cpp11/http/server2/request_handler.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include "mime_types.hpp" #include "reply.hpp" #include "request.hpp" @@ -74,7 +73,7 @@ void request_handler::handle_request(const request& req, reply& rep) rep.content.append(buf, is.gcount()); rep.headers.resize(2); rep.headers[0].name = "Content-Length"; - rep.headers[0].value = boost::lexical_cast(rep.content.size()); + rep.headers[0].value = std::to_string(rep.content.size()); rep.headers[1].name = "Content-Type"; rep.headers[1].value = mime_types::extension_to_type(extension); } diff --git a/asio/src/examples/cpp03/http/server2/request_handler.hpp b/asio/src/examples/cpp11/http/server2/request_handler.hpp similarity index 90% rename from asio/src/examples/cpp03/http/server2/request_handler.hpp rename to asio/src/examples/cpp11/http/server2/request_handler.hpp index 88ac16628a..d9baeb7f89 100644 --- a/asio/src/examples/cpp03/http/server2/request_handler.hpp +++ b/asio/src/examples/cpp11/http/server2/request_handler.hpp @@ -12,7 +12,6 @@ #define HTTP_SERVER2_REQUEST_HANDLER_HPP #include -#include namespace http { namespace server2 { @@ -22,9 +21,11 @@ struct request; /// The common handler for all incoming requests. class request_handler - : private boost::noncopyable { public: + request_handler(const request_handler&) = delete; + request_handler& operator=(const request_handler&) = delete; + /// Construct with a directory containing files to be served. explicit request_handler(const std::string& doc_root); diff --git a/asio/src/examples/cpp03/http/server2/request_parser.cpp b/asio/src/examples/cpp11/http/server2/request_parser.cpp similarity index 75% rename from asio/src/examples/cpp03/http/server2/request_parser.cpp rename to asio/src/examples/cpp11/http/server2/request_parser.cpp index fdeb7e5c17..d27392505a 100644 --- a/asio/src/examples/cpp03/http/server2/request_parser.cpp +++ b/asio/src/examples/cpp11/http/server2/request_parser.cpp @@ -24,90 +24,90 @@ void request_parser::reset() state_ = method_start; } -boost::tribool request_parser::consume(request& req, char input) +request_parser::result_type request_parser::consume(request& req, char input) { switch (state_) { case method_start: if (!is_char(input) || is_ctl(input) || is_tspecial(input)) { - return false; + return bad; } else { state_ = method; req.method.push_back(input); - return boost::indeterminate; + return indeterminate; } case method: if (input == ' ') { state_ = uri; - return boost::indeterminate; + return indeterminate; } else if (!is_char(input) || is_ctl(input) || is_tspecial(input)) { - return false; + return bad; } else { req.method.push_back(input); - return boost::indeterminate; + return indeterminate; } case uri: if (input == ' ') { state_ = http_version_h; - return boost::indeterminate; + return indeterminate; } else if (is_ctl(input)) { - return false; + return bad; } else { req.uri.push_back(input); - return boost::indeterminate; + return indeterminate; } case http_version_h: if (input == 'H') { state_ = http_version_t_1; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case http_version_t_1: if (input == 'T') { state_ = http_version_t_2; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case http_version_t_2: if (input == 'T') { state_ = http_version_p; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case http_version_p: if (input == 'P') { state_ = http_version_slash; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case http_version_slash: if (input == '/') @@ -115,170 +115,170 @@ boost::tribool request_parser::consume(request& req, char input) req.http_version_major = 0; req.http_version_minor = 0; state_ = http_version_major_start; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case http_version_major_start: if (is_digit(input)) { req.http_version_major = req.http_version_major * 10 + input - '0'; state_ = http_version_major; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case http_version_major: if (input == '.') { state_ = http_version_minor_start; - return boost::indeterminate; + return indeterminate; } else if (is_digit(input)) { req.http_version_major = req.http_version_major * 10 + input - '0'; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case http_version_minor_start: if (is_digit(input)) { req.http_version_minor = req.http_version_minor * 10 + input - '0'; state_ = http_version_minor; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case http_version_minor: if (input == '\r') { state_ = expecting_newline_1; - return boost::indeterminate; + return indeterminate; } else if (is_digit(input)) { req.http_version_minor = req.http_version_minor * 10 + input - '0'; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case expecting_newline_1: if (input == '\n') { state_ = header_line_start; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case header_line_start: if (input == '\r') { state_ = expecting_newline_3; - return boost::indeterminate; + return indeterminate; } else if (!req.headers.empty() && (input == ' ' || input == '\t')) { state_ = header_lws; - return boost::indeterminate; + return indeterminate; } else if (!is_char(input) || is_ctl(input) || is_tspecial(input)) { - return false; + return bad; } else { req.headers.push_back(header()); req.headers.back().name.push_back(input); state_ = header_name; - return boost::indeterminate; + return indeterminate; } case header_lws: if (input == '\r') { state_ = expecting_newline_2; - return boost::indeterminate; + return indeterminate; } else if (input == ' ' || input == '\t') { - return boost::indeterminate; + return indeterminate; } else if (is_ctl(input)) { - return false; + return bad; } else { state_ = header_value; req.headers.back().value.push_back(input); - return boost::indeterminate; + return indeterminate; } case header_name: if (input == ':') { state_ = space_before_header_value; - return boost::indeterminate; + return indeterminate; } else if (!is_char(input) || is_ctl(input) || is_tspecial(input)) { - return false; + return bad; } else { req.headers.back().name.push_back(input); - return boost::indeterminate; + return indeterminate; } case space_before_header_value: if (input == ' ') { state_ = header_value; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case header_value: if (input == '\r') { state_ = expecting_newline_2; - return boost::indeterminate; + return indeterminate; } else if (is_ctl(input)) { - return false; + return bad; } else { req.headers.back().value.push_back(input); - return boost::indeterminate; + return indeterminate; } case expecting_newline_2: if (input == '\n') { state_ = header_line_start; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case expecting_newline_3: - return (input == '\n'); + return (input == '\n') ? good : bad; default: - return false; + return bad; } } diff --git a/asio/src/examples/cpp03/http/server2/request_parser.hpp b/asio/src/examples/cpp11/http/server2/request_parser.hpp similarity index 71% rename from asio/src/examples/cpp03/http/server2/request_parser.hpp rename to asio/src/examples/cpp11/http/server2/request_parser.hpp index 2d591c2e10..8bfe18cce1 100644 --- a/asio/src/examples/cpp03/http/server2/request_parser.hpp +++ b/asio/src/examples/cpp11/http/server2/request_parser.hpp @@ -11,8 +11,7 @@ #ifndef HTTP_SERVER2_REQUEST_PARSER_HPP #define HTTP_SERVER2_REQUEST_PARSER_HPP -#include -#include +#include namespace http { namespace server2 { @@ -29,27 +28,29 @@ class request_parser /// Reset to initial parser state. void reset(); - /// Parse some data. The tribool return value is true when a complete request - /// has been parsed, false if the data is invalid, indeterminate when more - /// data is required. The InputIterator return value indicates how much of the - /// input has been consumed. + /// Result of parse. + enum result_type { good, bad, indeterminate }; + + /// Parse some data. The enum return value is good when a complete request has + /// been parsed, bad if the data is invalid, indeterminate when more data is + /// required. The InputIterator return value indicates how much of the input + /// has been consumed. template - boost::tuple parse(request& req, + std::tuple parse(request& req, InputIterator begin, InputIterator end) { while (begin != end) { - boost::tribool result = consume(req, *begin++); - if (result || !result) - return boost::make_tuple(result, begin); + result_type result = consume(req, *begin++); + if (result == good || result == bad) + return std::make_tuple(result, begin); } - boost::tribool result = boost::indeterminate; - return boost::make_tuple(result, begin); + return std::make_tuple(indeterminate, begin); } private: /// Handle the next character of input. - boost::tribool consume(request& req, char input); + result_type consume(request& req, char input); /// Check if a byte is an HTTP character. static bool is_char(int c); diff --git a/asio/src/examples/cpp03/http/server2/server.cpp b/asio/src/examples/cpp11/http/server2/server.cpp similarity index 65% rename from asio/src/examples/cpp03/http/server2/server.cpp rename to asio/src/examples/cpp11/http/server2/server.cpp index f2133c8747..8dc12fb867 100644 --- a/asio/src/examples/cpp03/http/server2/server.cpp +++ b/asio/src/examples/cpp11/http/server2/server.cpp @@ -9,7 +9,9 @@ // #include "server.hpp" -#include +#include +#include +#include "connection.hpp" namespace http { namespace server2 { @@ -19,7 +21,6 @@ server::server(const std::string& address, const std::string& port, : io_context_pool_(io_context_pool_size), signals_(io_context_pool_.get_io_context()), acceptor_(io_context_pool_.get_io_context()), - new_connection_(), request_handler_(doc_root) { // Register to handle the signals that indicate when the server should exit. @@ -30,7 +31,8 @@ server::server(const std::string& address, const std::string& port, #if defined(SIGQUIT) signals_.add(SIGQUIT); #endif // defined(SIGQUIT) - signals_.async_wait(boost::bind(&server::handle_stop, this)); + + do_await_stop(); // Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR). asio::ip::tcp::resolver resolver(acceptor_.get_executor()); @@ -41,7 +43,7 @@ server::server(const std::string& address, const std::string& port, acceptor_.bind(endpoint); acceptor_.listen(); - start_accept(); + do_accept(); } void server::run() @@ -49,28 +51,35 @@ void server::run() io_context_pool_.run(); } -void server::start_accept() +void server::do_accept() { - new_connection_.reset(new connection( - io_context_pool_.get_io_context(), request_handler_)); - acceptor_.async_accept(new_connection_->socket(), - boost::bind(&server::handle_accept, this, - asio::placeholders::error)); -} + acceptor_.async_accept(io_context_pool_.get_io_context(), + [this](std::error_code ec, asio::ip::tcp::socket socket) + { + // Check whether the server was stopped by a signal before this + // completion handler had a chance to run. + if (!acceptor_.is_open()) + { + return; + } -void server::handle_accept(const asio::error_code& e) -{ - if (!e) - { - new_connection_->start(); - } + if (!ec) + { + std::make_shared( + std::move(socket), request_handler_)->start(); + } - start_accept(); + do_accept(); + }); } -void server::handle_stop() +void server::do_await_stop() { - io_context_pool_.stop(); + signals_.async_wait( + [this](std::error_code /*ec*/, int /*signo*/) + { + io_context_pool_.stop(); + }); } } // namespace server2 diff --git a/asio/src/examples/cpp03/http/server2/server.hpp b/asio/src/examples/cpp11/http/server2/server.hpp similarity index 74% rename from asio/src/examples/cpp03/http/server2/server.hpp rename to asio/src/examples/cpp11/http/server2/server.hpp index 2674f19144..f647df3739 100644 --- a/asio/src/examples/cpp03/http/server2/server.hpp +++ b/asio/src/examples/cpp11/http/server2/server.hpp @@ -13,10 +13,6 @@ #include #include -#include -#include -#include -#include "connection.hpp" #include "io_context_pool.hpp" #include "request_handler.hpp" @@ -25,9 +21,11 @@ namespace server2 { /// The top-level class of the HTTP server. class server - : private boost::noncopyable { public: + server(const server&) = delete; + server& operator=(const server&) = delete; + /// Construct the server to listen on the specified TCP address and port, and /// serve up files from the given directory. explicit server(const std::string& address, const std::string& port, @@ -37,14 +35,11 @@ class server void run(); private: - /// Initiate an asynchronous accept operation. - void start_accept(); - - /// Handle completion of an asynchronous accept operation. - void handle_accept(const asio::error_code& e); + /// Perform an asynchronous accept operation. + void do_accept(); - /// Handle a request to stop the server. - void handle_stop(); + /// Wait for a request to stop the server. + void do_await_stop(); /// The pool of io_context objects used to perform asynchronous operations. io_context_pool io_context_pool_; @@ -55,9 +50,6 @@ class server /// Acceptor used to listen for incoming connections. asio::ip::tcp::acceptor acceptor_; - /// The next connection to be accepted. - connection_ptr new_connection_; - /// The handler for all incoming requests. request_handler request_handler_; }; diff --git a/asio/src/examples/cpp03/echo/.gitignore b/asio/src/examples/cpp11/http/server3/.gitignore similarity index 100% rename from asio/src/examples/cpp03/echo/.gitignore rename to asio/src/examples/cpp11/http/server3/.gitignore diff --git a/asio/src/examples/cpp11/http/server3/connection.cpp b/asio/src/examples/cpp11/http/server3/connection.cpp new file mode 100644 index 0000000000..5b48a0afb6 --- /dev/null +++ b/asio/src/examples/cpp11/http/server3/connection.cpp @@ -0,0 +1,89 @@ +// +// connection.cpp +// ~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include "connection.hpp" +#include +#include "request_handler.hpp" + +namespace http { +namespace server3 { + +connection::connection(asio::ip::tcp::socket socket, + request_handler& handler) + : socket_(std::move(socket)), + request_handler_(handler) +{ +} + +void connection::start() +{ + do_read(); +} + +void connection::do_read() +{ + auto self(shared_from_this()); + socket_.async_read_some(asio::buffer(buffer_), + [this, self](std::error_code ec, std::size_t bytes_transferred) + { + if (!ec) + { + request_parser::result_type result; + std::tie(result, std::ignore) = request_parser_.parse( + request_, buffer_.data(), buffer_.data() + bytes_transferred); + + if (result == request_parser::good) + { + request_handler_.handle_request(request_, reply_); + do_write(); + } + else if (result == request_parser::bad) + { + reply_ = reply::stock_reply(reply::bad_request); + do_write(); + } + else + { + do_read(); + } + } + + // If an error occurs then no new asynchronous operations are + // started. This means that all shared_ptr references to the + // connection object will disappear and the object will be + // destroyed automatically after this handler returns. The + // connection class's destructor closes the socket. + }); +} + +void connection::do_write() +{ + auto self(shared_from_this()); + asio::async_write(socket_, reply_.to_buffers(), + [this, self](std::error_code ec, std::size_t) + { + if (!ec) + { + // Initiate graceful connection closure. + std::error_code ignored_ec; + socket_.shutdown(asio::ip::tcp::socket::shutdown_both, + ignored_ec); + } + + // No new asynchronous operations are started. This means that + // all shared_ptr references to the connection object will + // disappear and the object will be destroyed automatically after + // this handler returns. The connection class's destructor closes + // the socket. + }); +} + +} // namespace server3 +} // namespace http diff --git a/asio/src/examples/cpp03/http/server3/connection.hpp b/asio/src/examples/cpp11/http/server3/connection.hpp similarity index 57% rename from asio/src/examples/cpp03/http/server3/connection.hpp rename to asio/src/examples/cpp11/http/server3/connection.hpp index a28e9e9693..7d9c6dffab 100644 --- a/asio/src/examples/cpp03/http/server3/connection.hpp +++ b/asio/src/examples/cpp11/http/server3/connection.hpp @@ -12,10 +12,8 @@ #define HTTP_SERVER3_CONNECTION_HPP #include -#include -#include -#include -#include +#include +#include #include "reply.hpp" #include "request.hpp" #include "request_handler.hpp" @@ -26,30 +24,25 @@ namespace server3 { /// Represents a single connection from a client. class connection - : public boost::enable_shared_from_this, - private boost::noncopyable + : public std::enable_shared_from_this { public: - /// Construct a connection with the given io_context. - explicit connection(asio::io_context& io_context, - request_handler& handler); + connection(const connection&) = delete; + connection& operator=(const connection&) = delete; - /// Get the socket associated with the connection. - asio::ip::tcp::socket& socket(); + /// Construct a connection with the given socket. + explicit connection(asio::ip::tcp::socket socket, + request_handler& handler); /// Start the first asynchronous operation for the connection. void start(); private: - /// Handle completion of a read operation. - void handle_read(const asio::error_code& e, - std::size_t bytes_transferred); - - /// Handle completion of a write operation. - void handle_write(const asio::error_code& e); + /// Perform an asynchronous read operation. + void do_read(); - /// Strand to ensure the connection's handlers are not called concurrently. - asio::strand strand_; + /// Perform an asynchronous write operation. + void do_write(); /// Socket for the connection. asio::ip::tcp::socket socket_; @@ -58,7 +51,7 @@ class connection request_handler& request_handler_; /// Buffer for incoming data. - boost::array buffer_; + std::array buffer_; /// The incoming request. request request_; @@ -70,7 +63,7 @@ class connection reply reply_; }; -typedef boost::shared_ptr connection_ptr; +typedef std::shared_ptr connection_ptr; } // namespace server3 } // namespace http diff --git a/asio/src/examples/cpp03/http/server3/header.hpp b/asio/src/examples/cpp11/http/server3/header.hpp similarity index 100% rename from asio/src/examples/cpp03/http/server3/header.hpp rename to asio/src/examples/cpp11/http/server3/header.hpp diff --git a/asio/src/examples/cpp03/http/server3/main.cpp b/asio/src/examples/cpp11/http/server3/main.cpp similarity index 87% rename from asio/src/examples/cpp03/http/server3/main.cpp rename to asio/src/examples/cpp11/http/server3/main.cpp index 3694be4164..0b945687ff 100644 --- a/asio/src/examples/cpp03/http/server3/main.cpp +++ b/asio/src/examples/cpp11/http/server3/main.cpp @@ -11,8 +11,6 @@ #include #include #include -#include -#include #include "server.hpp" int main(int argc, char* argv[]) @@ -31,7 +29,7 @@ int main(int argc, char* argv[]) } // Initialise the server. - std::size_t num_threads = boost::lexical_cast(argv[3]); + std::size_t num_threads = std::stoi(argv[3]); http::server3::server s(argv[1], argv[2], argv[4], num_threads); // Run the server until stopped. diff --git a/asio/src/examples/cpp03/http/server3/mime_types.cpp b/asio/src/examples/cpp11/http/server3/mime_types.cpp similarity index 100% rename from asio/src/examples/cpp03/http/server3/mime_types.cpp rename to asio/src/examples/cpp11/http/server3/mime_types.cpp diff --git a/asio/src/examples/cpp03/http/server3/mime_types.hpp b/asio/src/examples/cpp11/http/server3/mime_types.hpp similarity index 100% rename from asio/src/examples/cpp03/http/server3/mime_types.hpp rename to asio/src/examples/cpp11/http/server3/mime_types.hpp diff --git a/asio/src/examples/cpp03/http/server3/reply.cpp b/asio/src/examples/cpp11/http/server3/reply.cpp similarity index 98% rename from asio/src/examples/cpp03/http/server3/reply.cpp rename to asio/src/examples/cpp11/http/server3/reply.cpp index 78ce3b6639..fbe4de33e7 100644 --- a/asio/src/examples/cpp03/http/server3/reply.cpp +++ b/asio/src/examples/cpp11/http/server3/reply.cpp @@ -10,7 +10,6 @@ #include "reply.hpp" #include -#include namespace http { namespace server3 { @@ -246,7 +245,7 @@ reply reply::stock_reply(reply::status_type status) rep.content = stock_replies::to_string(status); rep.headers.resize(2); rep.headers[0].name = "Content-Length"; - rep.headers[0].value = boost::lexical_cast(rep.content.size()); + rep.headers[0].value = std::to_string(rep.content.size()); rep.headers[1].name = "Content-Type"; rep.headers[1].value = "text/html"; return rep; diff --git a/asio/src/examples/cpp03/http/server3/reply.hpp b/asio/src/examples/cpp11/http/server3/reply.hpp similarity index 100% rename from asio/src/examples/cpp03/http/server3/reply.hpp rename to asio/src/examples/cpp11/http/server3/reply.hpp diff --git a/asio/src/examples/cpp03/http/server3/request.hpp b/asio/src/examples/cpp11/http/server3/request.hpp similarity index 100% rename from asio/src/examples/cpp03/http/server3/request.hpp rename to asio/src/examples/cpp11/http/server3/request.hpp diff --git a/asio/src/examples/cpp03/http/server3/request_handler.cpp b/asio/src/examples/cpp11/http/server3/request_handler.cpp similarity index 96% rename from asio/src/examples/cpp03/http/server3/request_handler.cpp rename to asio/src/examples/cpp11/http/server3/request_handler.cpp index d3a482362f..6968c33b4e 100644 --- a/asio/src/examples/cpp03/http/server3/request_handler.cpp +++ b/asio/src/examples/cpp11/http/server3/request_handler.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include "mime_types.hpp" #include "reply.hpp" #include "request.hpp" @@ -74,7 +73,7 @@ void request_handler::handle_request(const request& req, reply& rep) rep.content.append(buf, is.gcount()); rep.headers.resize(2); rep.headers[0].name = "Content-Length"; - rep.headers[0].value = boost::lexical_cast(rep.content.size()); + rep.headers[0].value = std::to_string(rep.content.size()); rep.headers[1].name = "Content-Type"; rep.headers[1].value = mime_types::extension_to_type(extension); } diff --git a/asio/src/examples/cpp03/http/server3/request_handler.hpp b/asio/src/examples/cpp11/http/server3/request_handler.hpp similarity index 90% rename from asio/src/examples/cpp03/http/server3/request_handler.hpp rename to asio/src/examples/cpp11/http/server3/request_handler.hpp index fbb27dcd7e..a23e1a2dd4 100644 --- a/asio/src/examples/cpp03/http/server3/request_handler.hpp +++ b/asio/src/examples/cpp11/http/server3/request_handler.hpp @@ -12,7 +12,6 @@ #define HTTP_SERVER3_REQUEST_HANDLER_HPP #include -#include namespace http { namespace server3 { @@ -22,9 +21,11 @@ struct request; /// The common handler for all incoming requests. class request_handler - : private boost::noncopyable { public: + request_handler(const request_handler&) = delete; + request_handler& operator=(const request_handler&) = delete; + /// Construct with a directory containing files to be served. explicit request_handler(const std::string& doc_root); diff --git a/asio/src/examples/cpp03/http/server3/request_parser.cpp b/asio/src/examples/cpp11/http/server3/request_parser.cpp similarity index 75% rename from asio/src/examples/cpp03/http/server3/request_parser.cpp rename to asio/src/examples/cpp11/http/server3/request_parser.cpp index e4a36aa34d..c141436eb7 100644 --- a/asio/src/examples/cpp03/http/server3/request_parser.cpp +++ b/asio/src/examples/cpp11/http/server3/request_parser.cpp @@ -24,90 +24,90 @@ void request_parser::reset() state_ = method_start; } -boost::tribool request_parser::consume(request& req, char input) +request_parser::result_type request_parser::consume(request& req, char input) { switch (state_) { case method_start: if (!is_char(input) || is_ctl(input) || is_tspecial(input)) { - return false; + return bad; } else { state_ = method; req.method.push_back(input); - return boost::indeterminate; + return indeterminate; } case method: if (input == ' ') { state_ = uri; - return boost::indeterminate; + return indeterminate; } else if (!is_char(input) || is_ctl(input) || is_tspecial(input)) { - return false; + return bad; } else { req.method.push_back(input); - return boost::indeterminate; + return indeterminate; } case uri: if (input == ' ') { state_ = http_version_h; - return boost::indeterminate; + return indeterminate; } else if (is_ctl(input)) { - return false; + return bad; } else { req.uri.push_back(input); - return boost::indeterminate; + return indeterminate; } case http_version_h: if (input == 'H') { state_ = http_version_t_1; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case http_version_t_1: if (input == 'T') { state_ = http_version_t_2; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case http_version_t_2: if (input == 'T') { state_ = http_version_p; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case http_version_p: if (input == 'P') { state_ = http_version_slash; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case http_version_slash: if (input == '/') @@ -115,170 +115,170 @@ boost::tribool request_parser::consume(request& req, char input) req.http_version_major = 0; req.http_version_minor = 0; state_ = http_version_major_start; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case http_version_major_start: if (is_digit(input)) { req.http_version_major = req.http_version_major * 10 + input - '0'; state_ = http_version_major; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case http_version_major: if (input == '.') { state_ = http_version_minor_start; - return boost::indeterminate; + return indeterminate; } else if (is_digit(input)) { req.http_version_major = req.http_version_major * 10 + input - '0'; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case http_version_minor_start: if (is_digit(input)) { req.http_version_minor = req.http_version_minor * 10 + input - '0'; state_ = http_version_minor; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case http_version_minor: if (input == '\r') { state_ = expecting_newline_1; - return boost::indeterminate; + return indeterminate; } else if (is_digit(input)) { req.http_version_minor = req.http_version_minor * 10 + input - '0'; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case expecting_newline_1: if (input == '\n') { state_ = header_line_start; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case header_line_start: if (input == '\r') { state_ = expecting_newline_3; - return boost::indeterminate; + return indeterminate; } else if (!req.headers.empty() && (input == ' ' || input == '\t')) { state_ = header_lws; - return boost::indeterminate; + return indeterminate; } else if (!is_char(input) || is_ctl(input) || is_tspecial(input)) { - return false; + return bad; } else { req.headers.push_back(header()); req.headers.back().name.push_back(input); state_ = header_name; - return boost::indeterminate; + return indeterminate; } case header_lws: if (input == '\r') { state_ = expecting_newline_2; - return boost::indeterminate; + return indeterminate; } else if (input == ' ' || input == '\t') { - return boost::indeterminate; + return indeterminate; } else if (is_ctl(input)) { - return false; + return bad; } else { state_ = header_value; req.headers.back().value.push_back(input); - return boost::indeterminate; + return indeterminate; } case header_name: if (input == ':') { state_ = space_before_header_value; - return boost::indeterminate; + return indeterminate; } else if (!is_char(input) || is_ctl(input) || is_tspecial(input)) { - return false; + return bad; } else { req.headers.back().name.push_back(input); - return boost::indeterminate; + return indeterminate; } case space_before_header_value: if (input == ' ') { state_ = header_value; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case header_value: if (input == '\r') { state_ = expecting_newline_2; - return boost::indeterminate; + return indeterminate; } else if (is_ctl(input)) { - return false; + return bad; } else { req.headers.back().value.push_back(input); - return boost::indeterminate; + return indeterminate; } case expecting_newline_2: if (input == '\n') { state_ = header_line_start; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case expecting_newline_3: - return (input == '\n'); + return (input == '\n') ? good : bad; default: - return false; + return bad; } } diff --git a/asio/src/examples/cpp03/http/server3/request_parser.hpp b/asio/src/examples/cpp11/http/server3/request_parser.hpp similarity index 71% rename from asio/src/examples/cpp03/http/server3/request_parser.hpp rename to asio/src/examples/cpp11/http/server3/request_parser.hpp index f866aff4a3..8eccdf6322 100644 --- a/asio/src/examples/cpp03/http/server3/request_parser.hpp +++ b/asio/src/examples/cpp11/http/server3/request_parser.hpp @@ -11,8 +11,7 @@ #ifndef HTTP_SERVER3_REQUEST_PARSER_HPP #define HTTP_SERVER3_REQUEST_PARSER_HPP -#include -#include +#include namespace http { namespace server3 { @@ -29,27 +28,29 @@ class request_parser /// Reset to initial parser state. void reset(); - /// Parse some data. The tribool return value is true when a complete request - /// has been parsed, false if the data is invalid, indeterminate when more - /// data is required. The InputIterator return value indicates how much of the - /// input has been consumed. + /// Result of parse. + enum result_type { good, bad, indeterminate }; + + /// Parse some data. The enum return value is good when a complete request has + /// been parsed, bad if the data is invalid, indeterminate when more data is + /// required. The InputIterator return value indicates how much of the input + /// has been consumed. template - boost::tuple parse(request& req, + std::tuple parse(request& req, InputIterator begin, InputIterator end) { while (begin != end) { - boost::tribool result = consume(req, *begin++); - if (result || !result) - return boost::make_tuple(result, begin); + result_type result = consume(req, *begin++); + if (result == good || result == bad) + return std::make_tuple(result, begin); } - boost::tribool result = boost::indeterminate; - return boost::make_tuple(result, begin); + return std::make_tuple(indeterminate, begin); } private: /// Handle the next character of input. - boost::tribool consume(request& req, char input); + result_type consume(request& req, char input); /// Check if a byte is an HTTP character. static bool is_char(int c); diff --git a/asio/src/examples/cpp03/http/server3/server.cpp b/asio/src/examples/cpp11/http/server3/server.cpp similarity index 58% rename from asio/src/examples/cpp03/http/server3/server.cpp rename to asio/src/examples/cpp11/http/server3/server.cpp index e5f48d1939..e12ce62a19 100644 --- a/asio/src/examples/cpp03/http/server3/server.cpp +++ b/asio/src/examples/cpp11/http/server3/server.cpp @@ -9,9 +9,11 @@ // #include "server.hpp" -#include -#include +#include +#include +#include #include +#include "connection.hpp" namespace http { namespace server3 { @@ -21,7 +23,6 @@ server::server(const std::string& address, const std::string& port, : thread_pool_size_(thread_pool_size), signals_(io_context_), acceptor_(io_context_), - new_connection_(), request_handler_(doc_root) { // Register to handle the signals that indicate when the server should exit. @@ -32,7 +33,8 @@ server::server(const std::string& address, const std::string& port, #if defined(SIGQUIT) signals_.add(SIGQUIT); #endif // defined(SIGQUIT) - signals_.async_wait(boost::bind(&server::handle_stop, this)); + + do_await_stop(); // Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR). asio::ip::tcp::resolver resolver(io_context_); @@ -43,46 +45,52 @@ server::server(const std::string& address, const std::string& port, acceptor_.bind(endpoint); acceptor_.listen(); - start_accept(); + do_accept(); } void server::run() { - // Create a pool of threads to run all of the io_contexts. - std::vector > threads; + // Create a pool of threads to run the io_context. + std::vector threads; for (std::size_t i = 0; i < thread_pool_size_; ++i) - { - boost::shared_ptr thread(new asio::thread( - boost::bind(&asio::io_context::run, &io_context_))); - threads.push_back(thread); - } + threads.emplace_back([this]{ io_context_.run(); }); // Wait for all threads in the pool to exit. for (std::size_t i = 0; i < threads.size(); ++i) - threads[i]->join(); + threads[i].join(); } -void server::start_accept() +void server::do_accept() { - new_connection_.reset(new connection(io_context_, request_handler_)); - acceptor_.async_accept(new_connection_->socket(), - boost::bind(&server::handle_accept, this, - asio::placeholders::error)); -} + // The newly accepted socket is put into its own strand to ensure that all + // completion handlers associated with the connection do not run concurrently. + acceptor_.async_accept(asio::make_strand(io_context_), + [this](std::error_code ec, asio::ip::tcp::socket socket) + { + // Check whether the server was stopped by a signal before this + // completion handler had a chance to run. + if (!acceptor_.is_open()) + { + return; + } -void server::handle_accept(const asio::error_code& e) -{ - if (!e) - { - new_connection_->start(); - } + if (!ec) + { + std::make_shared( + std::move(socket), request_handler_)->start(); + } - start_accept(); + do_accept(); + }); } -void server::handle_stop() +void server::do_await_stop() { - io_context_.stop(); + signals_.async_wait( + [this](std::error_code /*ec*/, int /*signo*/) + { + io_context_.stop(); + }); } } // namespace server3 diff --git a/asio/src/examples/cpp03/http/server3/server.hpp b/asio/src/examples/cpp11/http/server3/server.hpp similarity index 75% rename from asio/src/examples/cpp03/http/server3/server.hpp rename to asio/src/examples/cpp11/http/server3/server.hpp index 968615c990..38c72d2591 100644 --- a/asio/src/examples/cpp03/http/server3/server.hpp +++ b/asio/src/examples/cpp11/http/server3/server.hpp @@ -13,10 +13,6 @@ #include #include -#include -#include -#include -#include "connection.hpp" #include "request_handler.hpp" namespace http { @@ -24,9 +20,11 @@ namespace server3 { /// The top-level class of the HTTP server. class server - : private boost::noncopyable { public: + server(const server&) = delete; + server& operator=(const server&) = delete; + /// Construct the server to listen on the specified TCP address and port, and /// serve up files from the given directory. explicit server(const std::string& address, const std::string& port, @@ -36,14 +34,11 @@ class server void run(); private: - /// Initiate an asynchronous accept operation. - void start_accept(); - - /// Handle completion of an asynchronous accept operation. - void handle_accept(const asio::error_code& e); + /// Perform an asynchronous accept operation. + void do_accept(); - /// Handle a request to stop the server. - void handle_stop(); + /// Wait for a request to stop the server. + void do_await_stop(); /// The number of threads that will call io_context::run(). std::size_t thread_pool_size_; @@ -57,9 +52,6 @@ class server /// Acceptor used to listen for incoming connections. asio::ip::tcp::acceptor acceptor_; - /// The next connection to be accepted. - connection_ptr new_connection_; - /// The handler for all incoming requests. request_handler request_handler_; }; diff --git a/asio/src/examples/cpp03/http/server/.gitignore b/asio/src/examples/cpp11/http/server4/.gitignore similarity index 100% rename from asio/src/examples/cpp03/http/server/.gitignore rename to asio/src/examples/cpp11/http/server4/.gitignore diff --git a/asio/src/examples/cpp03/http/server4/file_handler.cpp b/asio/src/examples/cpp11/http/server4/file_handler.cpp similarity index 96% rename from asio/src/examples/cpp03/http/server4/file_handler.cpp rename to asio/src/examples/cpp11/http/server4/file_handler.cpp index 53ea3b5fab..e45ffdaf79 100644 --- a/asio/src/examples/cpp03/http/server4/file_handler.cpp +++ b/asio/src/examples/cpp11/http/server4/file_handler.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include "mime_types.hpp" #include "reply.hpp" #include "request.hpp" @@ -74,7 +73,7 @@ void file_handler::operator()(const request& req, reply& rep) rep.content.append(buf, is.gcount()); rep.headers.resize(2); rep.headers[0].name = "Content-Length"; - rep.headers[0].value = boost::lexical_cast(rep.content.size()); + rep.headers[0].value = std::to_string(rep.content.size()); rep.headers[1].name = "Content-Type"; rep.headers[1].value = mime_types::extension_to_type(extension); } diff --git a/asio/src/examples/cpp03/http/server4/file_handler.hpp b/asio/src/examples/cpp11/http/server4/file_handler.hpp similarity index 100% rename from asio/src/examples/cpp03/http/server4/file_handler.hpp rename to asio/src/examples/cpp11/http/server4/file_handler.hpp diff --git a/asio/src/examples/cpp03/http/server4/header.hpp b/asio/src/examples/cpp11/http/server4/header.hpp similarity index 100% rename from asio/src/examples/cpp03/http/server4/header.hpp rename to asio/src/examples/cpp11/http/server4/header.hpp diff --git a/asio/src/examples/cpp03/http/server4/main.cpp b/asio/src/examples/cpp11/http/server4/main.cpp similarity index 91% rename from asio/src/examples/cpp03/http/server4/main.cpp rename to asio/src/examples/cpp11/http/server4/main.cpp index fd2430b331..7d5a6da3d2 100644 --- a/asio/src/examples/cpp03/http/server4/main.cpp +++ b/asio/src/examples/cpp11/http/server4/main.cpp @@ -43,8 +43,11 @@ int main(int argc, char* argv[]) #if defined(SIGQUIT) signals.add(SIGQUIT); #endif // defined(SIGQUIT) - signals.async_wait(boost::bind( - &asio::io_context::stop, &io_context)); + signals.async_wait( + [&io_context](std::error_code, int) + { + io_context.stop(); + }); // Run the server. io_context.run(); diff --git a/asio/src/examples/cpp03/http/server4/mime_types.cpp b/asio/src/examples/cpp11/http/server4/mime_types.cpp similarity index 100% rename from asio/src/examples/cpp03/http/server4/mime_types.cpp rename to asio/src/examples/cpp11/http/server4/mime_types.cpp diff --git a/asio/src/examples/cpp03/http/server4/mime_types.hpp b/asio/src/examples/cpp11/http/server4/mime_types.hpp similarity index 100% rename from asio/src/examples/cpp03/http/server4/mime_types.hpp rename to asio/src/examples/cpp11/http/server4/mime_types.hpp diff --git a/asio/src/examples/cpp03/http/server4/reply.cpp b/asio/src/examples/cpp11/http/server4/reply.cpp similarity index 98% rename from asio/src/examples/cpp03/http/server4/reply.cpp rename to asio/src/examples/cpp11/http/server4/reply.cpp index 949f448d03..6de74d5856 100644 --- a/asio/src/examples/cpp03/http/server4/reply.cpp +++ b/asio/src/examples/cpp11/http/server4/reply.cpp @@ -10,7 +10,6 @@ #include "reply.hpp" #include -#include namespace http { namespace server4 { @@ -246,7 +245,7 @@ reply reply::stock_reply(reply::status_type status) rep.content = stock_replies::to_string(status); rep.headers.resize(2); rep.headers[0].name = "Content-Length"; - rep.headers[0].value = boost::lexical_cast(rep.content.size()); + rep.headers[0].value = std::to_string(rep.content.size()); rep.headers[1].name = "Content-Type"; rep.headers[1].value = "text/html"; return rep; diff --git a/asio/src/examples/cpp03/http/server4/reply.hpp b/asio/src/examples/cpp11/http/server4/reply.hpp similarity index 100% rename from asio/src/examples/cpp03/http/server4/reply.hpp rename to asio/src/examples/cpp11/http/server4/reply.hpp diff --git a/asio/src/examples/cpp03/http/server/request.hpp b/asio/src/examples/cpp11/http/server4/request.hpp similarity index 79% rename from asio/src/examples/cpp03/http/server/request.hpp rename to asio/src/examples/cpp11/http/server4/request.hpp index 68ab3e2bd0..fc7d480788 100644 --- a/asio/src/examples/cpp03/http/server/request.hpp +++ b/asio/src/examples/cpp11/http/server4/request.hpp @@ -8,15 +8,15 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#ifndef HTTP_REQUEST_HPP -#define HTTP_REQUEST_HPP +#ifndef HTTP_SERVER4_REQUEST_HPP +#define HTTP_SERVER4_REQUEST_HPP #include #include #include "header.hpp" namespace http { -namespace server { +namespace server4 { /// A request received from a client. struct request @@ -28,7 +28,7 @@ struct request std::vector
headers; }; -} // namespace server +} // namespace server4 } // namespace http -#endif // HTTP_REQUEST_HPP +#endif // HTTP_SERVER4_REQUEST_HPP diff --git a/asio/src/examples/cpp03/http/server/request_handler.cpp b/asio/src/examples/cpp11/http/server4/request_handler.cpp similarity index 94% rename from asio/src/examples/cpp03/http/server/request_handler.cpp rename to asio/src/examples/cpp11/http/server4/request_handler.cpp index 3a04a6e52c..5081a0dcf1 100644 --- a/asio/src/examples/cpp03/http/server/request_handler.cpp +++ b/asio/src/examples/cpp11/http/server4/request_handler.cpp @@ -12,13 +12,12 @@ #include #include #include -#include #include "mime_types.hpp" #include "reply.hpp" #include "request.hpp" namespace http { -namespace server { +namespace server4 { request_handler::request_handler(const std::string& doc_root) : doc_root_(doc_root) @@ -74,7 +73,7 @@ void request_handler::handle_request(const request& req, reply& rep) rep.content.append(buf, is.gcount()); rep.headers.resize(2); rep.headers[0].name = "Content-Length"; - rep.headers[0].value = boost::lexical_cast(rep.content.size()); + rep.headers[0].value = std::to_string(rep.content.size()); rep.headers[1].name = "Content-Type"; rep.headers[1].value = mime_types::extension_to_type(extension); } @@ -118,5 +117,5 @@ bool request_handler::url_decode(const std::string& in, std::string& out) return true; } -} // namespace server +} // namespace server4 } // namespace http diff --git a/asio/src/examples/cpp03/http/server/request_handler.hpp b/asio/src/examples/cpp11/http/server4/request_handler.hpp similarity index 76% rename from asio/src/examples/cpp03/http/server/request_handler.hpp rename to asio/src/examples/cpp11/http/server4/request_handler.hpp index 1af9fa5188..0063bb9b1c 100644 --- a/asio/src/examples/cpp03/http/server/request_handler.hpp +++ b/asio/src/examples/cpp11/http/server4/request_handler.hpp @@ -8,23 +8,24 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#ifndef HTTP_REQUEST_HANDLER_HPP -#define HTTP_REQUEST_HANDLER_HPP +#ifndef HTTP_SERVER4_REQUEST_HANDLER_HPP +#define HTTP_SERVER4_REQUEST_HANDLER_HPP #include -#include namespace http { -namespace server { +namespace server4 { struct reply; struct request; /// The common handler for all incoming requests. class request_handler - : private boost::noncopyable { public: + request_handler(const request_handler&) = delete; + request_handler& operator=(const request_handler&) = delete; + /// Construct with a directory containing files to be served. explicit request_handler(const std::string& doc_root); @@ -40,7 +41,7 @@ class request_handler static bool url_decode(const std::string& in, std::string& out); }; -} // namespace server +} // namespace server4 } // namespace http -#endif // HTTP_REQUEST_HANDLER_HPP +#endif // HTTP_SERVER4_REQUEST_HANDLER_HPP diff --git a/asio/src/examples/cpp03/http/server/request_parser.cpp b/asio/src/examples/cpp11/http/server4/request_parser.cpp similarity index 75% rename from asio/src/examples/cpp03/http/server/request_parser.cpp rename to asio/src/examples/cpp11/http/server4/request_parser.cpp index e64c703c9b..fc504e99de 100644 --- a/asio/src/examples/cpp03/http/server/request_parser.cpp +++ b/asio/src/examples/cpp11/http/server4/request_parser.cpp @@ -12,7 +12,7 @@ #include "request.hpp" namespace http { -namespace server { +namespace server4 { request_parser::request_parser() : state_(method_start) @@ -24,90 +24,90 @@ void request_parser::reset() state_ = method_start; } -boost::tribool request_parser::consume(request& req, char input) +request_parser::result_type request_parser::consume(request& req, char input) { switch (state_) { case method_start: if (!is_char(input) || is_ctl(input) || is_tspecial(input)) { - return false; + return bad; } else { state_ = method; req.method.push_back(input); - return boost::indeterminate; + return indeterminate; } case method: if (input == ' ') { state_ = uri; - return boost::indeterminate; + return indeterminate; } else if (!is_char(input) || is_ctl(input) || is_tspecial(input)) { - return false; + return bad; } else { req.method.push_back(input); - return boost::indeterminate; + return indeterminate; } case uri: if (input == ' ') { state_ = http_version_h; - return boost::indeterminate; + return indeterminate; } else if (is_ctl(input)) { - return false; + return bad; } else { req.uri.push_back(input); - return boost::indeterminate; + return indeterminate; } case http_version_h: if (input == 'H') { state_ = http_version_t_1; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case http_version_t_1: if (input == 'T') { state_ = http_version_t_2; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case http_version_t_2: if (input == 'T') { state_ = http_version_p; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case http_version_p: if (input == 'P') { state_ = http_version_slash; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case http_version_slash: if (input == '/') @@ -115,170 +115,170 @@ boost::tribool request_parser::consume(request& req, char input) req.http_version_major = 0; req.http_version_minor = 0; state_ = http_version_major_start; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case http_version_major_start: if (is_digit(input)) { req.http_version_major = req.http_version_major * 10 + input - '0'; state_ = http_version_major; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case http_version_major: if (input == '.') { state_ = http_version_minor_start; - return boost::indeterminate; + return indeterminate; } else if (is_digit(input)) { req.http_version_major = req.http_version_major * 10 + input - '0'; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case http_version_minor_start: if (is_digit(input)) { req.http_version_minor = req.http_version_minor * 10 + input - '0'; state_ = http_version_minor; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case http_version_minor: if (input == '\r') { state_ = expecting_newline_1; - return boost::indeterminate; + return indeterminate; } else if (is_digit(input)) { req.http_version_minor = req.http_version_minor * 10 + input - '0'; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case expecting_newline_1: if (input == '\n') { state_ = header_line_start; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case header_line_start: if (input == '\r') { state_ = expecting_newline_3; - return boost::indeterminate; + return indeterminate; } else if (!req.headers.empty() && (input == ' ' || input == '\t')) { state_ = header_lws; - return boost::indeterminate; + return indeterminate; } else if (!is_char(input) || is_ctl(input) || is_tspecial(input)) { - return false; + return bad; } else { req.headers.push_back(header()); req.headers.back().name.push_back(input); state_ = header_name; - return boost::indeterminate; + return indeterminate; } case header_lws: if (input == '\r') { state_ = expecting_newline_2; - return boost::indeterminate; + return indeterminate; } else if (input == ' ' || input == '\t') { - return boost::indeterminate; + return indeterminate; } else if (is_ctl(input)) { - return false; + return bad; } else { state_ = header_value; req.headers.back().value.push_back(input); - return boost::indeterminate; + return indeterminate; } case header_name: if (input == ':') { state_ = space_before_header_value; - return boost::indeterminate; + return indeterminate; } else if (!is_char(input) || is_ctl(input) || is_tspecial(input)) { - return false; + return bad; } else { req.headers.back().name.push_back(input); - return boost::indeterminate; + return indeterminate; } case space_before_header_value: if (input == ' ') { state_ = header_value; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case header_value: if (input == '\r') { state_ = expecting_newline_2; - return boost::indeterminate; + return indeterminate; } else if (is_ctl(input)) { - return false; + return bad; } else { req.headers.back().value.push_back(input); - return boost::indeterminate; + return indeterminate; } case expecting_newline_2: if (input == '\n') { state_ = header_line_start; - return boost::indeterminate; + return indeterminate; } else { - return false; + return bad; } case expecting_newline_3: - return (input == '\n'); + return (input == '\n') ? good : bad; default: - return false; + return bad; } } @@ -311,5 +311,5 @@ bool request_parser::is_digit(int c) return c >= '0' && c <= '9'; } -} // namespace server +} // namespace server4 } // namespace http diff --git a/asio/src/examples/cpp03/http/server/request_parser.hpp b/asio/src/examples/cpp11/http/server4/request_parser.hpp similarity index 65% rename from asio/src/examples/cpp03/http/server/request_parser.hpp rename to asio/src/examples/cpp11/http/server4/request_parser.hpp index 4563f9f31c..a8c86cd423 100644 --- a/asio/src/examples/cpp03/http/server/request_parser.hpp +++ b/asio/src/examples/cpp11/http/server4/request_parser.hpp @@ -8,14 +8,13 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#ifndef HTTP_REQUEST_PARSER_HPP -#define HTTP_REQUEST_PARSER_HPP +#ifndef HTTP_SERVER4_REQUEST_PARSER_HPP +#define HTTP_SERVER4_REQUEST_PARSER_HPP -#include -#include +#include namespace http { -namespace server { +namespace server4 { struct request; @@ -29,27 +28,29 @@ class request_parser /// Reset to initial parser state. void reset(); - /// Parse some data. The tribool return value is true when a complete request - /// has been parsed, false if the data is invalid, indeterminate when more - /// data is required. The InputIterator return value indicates how much of the - /// input has been consumed. + /// Result of parse. + enum result_type { good, bad, indeterminate }; + + /// Parse some data. The enum return value is good when a complete request has + /// been parsed, bad if the data is invalid, indeterminate when more data is + /// required. The InputIterator return value indicates how much of the input + /// has been consumed. template - boost::tuple parse(request& req, + std::tuple parse(request& req, InputIterator begin, InputIterator end) { while (begin != end) { - boost::tribool result = consume(req, *begin++); - if (result || !result) - return boost::make_tuple(result, begin); + result_type result = consume(req, *begin++); + if (result == good || result == bad) + return std::make_tuple(result, begin); } - boost::tribool result = boost::indeterminate; - return boost::make_tuple(result, begin); + return std::make_tuple(indeterminate, begin); } private: /// Handle the next character of input. - boost::tribool consume(request& req, char input); + result_type consume(request& req, char input); /// Check if a byte is an HTTP character. static bool is_char(int c); @@ -89,7 +90,7 @@ class request_parser } state_; }; -} // namespace server +} // namespace server4 } // namespace http -#endif // HTTP_REQUEST_PARSER_HPP +#endif // HTTP_SERVER4_REQUEST_PARSER_HPP diff --git a/asio/src/examples/cpp03/http/server4/server.cpp b/asio/src/examples/cpp11/http/server4/server.cpp similarity index 92% rename from asio/src/examples/cpp03/http/server4/server.cpp rename to asio/src/examples/cpp11/http/server4/server.cpp index a1b24ce44e..ff1f9028ba 100644 --- a/asio/src/examples/cpp03/http/server4/server.cpp +++ b/asio/src/examples/cpp11/http/server4/server.cpp @@ -17,7 +17,7 @@ namespace server4 { server::server(asio::io_context& io_context, const std::string& address, const std::string& port, - boost::function request_handler) + std::function request_handler) : request_handler_(request_handler) { tcp::resolver resolver(io_context); @@ -29,7 +29,7 @@ server::server(asio::io_context& io_context, // Enable the pseudo-keywords reenter, yield and fork. #include -void server::operator()(asio::error_code ec, std::size_t length) +void server::operator()(std::error_code ec, std::size_t length) { // In this example we keep the error handling code in one place by // hoisting it outside the coroutine. An alternative approach would be to @@ -67,7 +67,7 @@ void server::operator()(asio::error_code ec, std::size_t length) } while (is_parent()); // Create the objects needed to receive a request on the connection. - buffer_.reset(new boost::array); + buffer_.reset(new std::array); request_.reset(new request); // Loop until a complete request (or an invalid one) has been received. @@ -79,17 +79,17 @@ void server::operator()(asio::error_code ec, std::size_t length) yield socket_->async_read_some(asio::buffer(*buffer_), *this); // Parse the data we just received. - boost::tie(valid_request_, boost::tuples::ignore) + std::tie(parse_result_, std::ignore) = request_parser_.parse(*request_, buffer_->data(), buffer_->data() + length); // An indeterminate result means we need more data, so keep looping. - } while (boost::indeterminate(valid_request_)); + } while (parse_result_ == request_parser::indeterminate); // Create the reply object that will be sent back to the client. reply_.reset(new reply); - if (valid_request_) + if (parse_result_ == request_parser::good) { // A valid request was received. Call the user-supplied function object // to process the request and compose a reply. diff --git a/asio/src/examples/cpp03/http/server4/server.hpp b/asio/src/examples/cpp11/http/server4/server.hpp similarity index 72% rename from asio/src/examples/cpp03/http/server4/server.hpp rename to asio/src/examples/cpp11/http/server4/server.hpp index 21fc015483..f19a6706d9 100644 --- a/asio/src/examples/cpp03/http/server4/server.hpp +++ b/asio/src/examples/cpp11/http/server4/server.hpp @@ -12,10 +12,10 @@ #define HTTP_SERVER4_SERVER_HPP #include +#include +#include +#include #include -#include -#include -#include #include "request_parser.hpp" namespace http { @@ -32,39 +32,39 @@ class server : asio::coroutine /// serve up files from the given directory. explicit server(asio::io_context& io_context, const std::string& address, const std::string& port, - boost::function request_handler); + std::function request_handler); /// Perform work associated with the server. void operator()( - asio::error_code ec = asio::error_code(), + std::error_code ec = std::error_code(), std::size_t length = 0); private: typedef asio::ip::tcp tcp; /// The user-supplied handler for all incoming requests. - boost::function request_handler_; + std::function request_handler_; /// Acceptor used to listen for incoming connections. - boost::shared_ptr acceptor_; + std::shared_ptr acceptor_; /// The current connection from a client. - boost::shared_ptr socket_; + std::shared_ptr socket_; /// Buffer for incoming data. - boost::shared_ptr > buffer_; + std::shared_ptr> buffer_; /// The incoming request. - boost::shared_ptr request_; + std::shared_ptr request_; /// Whether the request is valid or not. - boost::tribool valid_request_; + request_parser::result_type parse_result_; /// The parser for the incoming request. request_parser request_parser_; /// The reply to be sent back to the client. - boost::shared_ptr reply_; + std::shared_ptr reply_; }; } // namespace server4 diff --git a/asio/src/examples/cpp03/icmp/.gitignore b/asio/src/examples/cpp11/icmp/.gitignore similarity index 100% rename from asio/src/examples/cpp03/icmp/.gitignore rename to asio/src/examples/cpp11/icmp/.gitignore diff --git a/asio/src/examples/cpp03/icmp/icmp_header.hpp b/asio/src/examples/cpp11/icmp/icmp_header.hpp similarity index 100% rename from asio/src/examples/cpp03/icmp/icmp_header.hpp rename to asio/src/examples/cpp11/icmp/icmp_header.hpp diff --git a/asio/src/examples/cpp03/icmp/ipv4_header.hpp b/asio/src/examples/cpp11/icmp/ipv4_header.hpp similarity index 100% rename from asio/src/examples/cpp03/icmp/ipv4_header.hpp rename to asio/src/examples/cpp11/icmp/ipv4_header.hpp diff --git a/asio/src/examples/cpp03/icmp/ping.cpp b/asio/src/examples/cpp11/icmp/ping.cpp similarity index 94% rename from asio/src/examples/cpp03/icmp/ping.cpp rename to asio/src/examples/cpp11/icmp/ping.cpp index ef6d2333c7..d871512777 100644 --- a/asio/src/examples/cpp03/icmp/ping.cpp +++ b/asio/src/examples/cpp11/icmp/ping.cpp @@ -9,7 +9,6 @@ // #include -#include #include #include #include @@ -59,7 +58,7 @@ class pinger // Wait up to five seconds for a reply. num_replies_ = 0; timer_.expires_at(time_sent_ + chrono::seconds(5)); - timer_.async_wait(boost::bind(&pinger::handle_timeout, this)); + timer_.async_wait(std::bind(&pinger::handle_timeout, this)); } void handle_timeout() @@ -69,7 +68,7 @@ class pinger // Requests must be sent no less than one second apart. timer_.expires_at(time_sent_ + chrono::seconds(1)); - timer_.async_wait(boost::bind(&pinger::start_send, this)); + timer_.async_wait(std::bind(&pinger::start_send, this)); } void start_receive() @@ -79,7 +78,7 @@ class pinger // Wait for a reply. We prepare the buffer to receive up to 64KB. socket_.async_receive(reply_buffer_.prepare(65536), - boost::bind(&pinger::handle_receive, this, boost::placeholders::_2)); + std::bind(&pinger::handle_receive, this, std::placeholders::_2)); } void handle_receive(std::size_t length) diff --git a/asio/src/examples/cpp11/invocation/prioritised_handlers.cpp b/asio/src/examples/cpp11/invocation/prioritised_handlers.cpp index 2ac2096e45..08ddb525cf 100644 --- a/asio/src/examples/cpp11/invocation/prioritised_handlers.cpp +++ b/asio/src/examples/cpp11/invocation/prioritised_handlers.cpp @@ -142,13 +142,13 @@ class handler_priority_queue : public asio::execution_context //---------------------------------------------------------------------- -void high_priority_handler(const asio::error_code& /*ec*/, +void high_priority_handler(const std::error_code& /*ec*/, tcp::socket /*socket*/) { std::cout << "High priority handler\n"; } -void middle_priority_handler(const asio::error_code& /*ec*/) +void middle_priority_handler(const std::error_code& /*ec*/) { std::cout << "Middle priority handler\n"; } diff --git a/asio/src/examples/cpp03/iostreams/daytime_client.cpp b/asio/src/examples/cpp11/iostreams/daytime_client.cpp similarity index 100% rename from asio/src/examples/cpp03/iostreams/daytime_client.cpp rename to asio/src/examples/cpp11/iostreams/daytime_client.cpp diff --git a/asio/src/examples/cpp03/iostreams/daytime_server.cpp b/asio/src/examples/cpp11/iostreams/daytime_server.cpp similarity index 97% rename from asio/src/examples/cpp03/iostreams/daytime_server.cpp rename to asio/src/examples/cpp11/iostreams/daytime_server.cpp index d9c03fbe37..da802fd1b4 100644 --- a/asio/src/examples/cpp03/iostreams/daytime_server.cpp +++ b/asio/src/examples/cpp11/iostreams/daytime_server.cpp @@ -34,7 +34,7 @@ int main() for (;;) { tcp::iostream stream; - asio::error_code ec; + std::error_code ec; acceptor.accept(stream.socket(), ec); if (!ec) { diff --git a/asio/src/examples/cpp11/local/connect_pair.cpp b/asio/src/examples/cpp11/local/connect_pair.cpp index fc8feb59a1..ed8b357699 100644 --- a/asio/src/examples/cpp11/local/connect_pair.cpp +++ b/asio/src/examples/cpp11/local/connect_pair.cpp @@ -44,7 +44,7 @@ class uppercase_filter } else { - throw asio::system_error(ec); + throw std::system_error(ec); } }); } @@ -61,7 +61,7 @@ class uppercase_filter } else { - throw asio::system_error(ec); + throw std::system_error(ec); } }); } diff --git a/asio/src/examples/cpp03/porthopper/.gitignore b/asio/src/examples/cpp11/porthopper/.gitignore similarity index 100% rename from asio/src/examples/cpp03/porthopper/.gitignore rename to asio/src/examples/cpp11/porthopper/.gitignore diff --git a/asio/src/examples/cpp03/porthopper/client.cpp b/asio/src/examples/cpp11/porthopper/client.cpp similarity index 75% rename from asio/src/examples/cpp03/porthopper/client.cpp rename to asio/src/examples/cpp11/porthopper/client.cpp index 97ab025dba..4206e46a71 100644 --- a/asio/src/examples/cpp03/porthopper/client.cpp +++ b/asio/src/examples/cpp11/porthopper/client.cpp @@ -9,18 +9,15 @@ // #include -#include -#include -#include -#include #include #include #include #include +#include #include +#include #include "protocol.hpp" -using namespace boost; using asio::ip::tcp; using asio::ip::udp; @@ -48,11 +45,10 @@ int main(int argc, char* argv[]) control_socket.connect(remote_endpoint); // Create a datagram socket to receive data from the server. - boost::shared_ptr data_socket( - new udp::socket(io_context, udp::endpoint(udp::v4(), 0))); + udp::socket data_socket(io_context, udp::endpoint(udp::v4(), 0)); // Determine what port we will receive data on. - udp::endpoint data_endpoint = data_socket->local_endpoint(); + udp::endpoint data_endpoint = data_socket.local_endpoint(); // Ask the server to start sending us data. control_request start = control_request::start(data_endpoint.port()); @@ -66,7 +62,7 @@ int main(int argc, char* argv[]) { // Receive a frame from the server. frame f; - data_socket->receive(f.to_buffers(), 0); + data_socket.receive(f.to_buffers(), 0); if (f.number() > last_frame_number) { last_frame_number = f.number(); @@ -80,20 +76,20 @@ int main(int argc, char* argv[]) std::cout << " Starting renegotiation"; // Create the new data socket. - boost::shared_ptr new_data_socket( - new udp::socket(io_context, udp::endpoint(udp::v4(), 0))); + udp::socket new_data_socket(io_context, udp::endpoint(udp::v4(), 0)); // Determine the new port we will use to receive data. - udp::endpoint new_data_endpoint = new_data_socket->local_endpoint(); + udp::endpoint new_data_endpoint = new_data_socket.local_endpoint(); // Ask the server to switch over to the new port. control_request change = control_request::change( data_endpoint.port(), new_data_endpoint.port()); - asio::error_code control_result; + std::error_code control_result; asio::async_write(control_socket, change.to_buffers(), - ( - lambda::var(control_result) = lambda::_1 - )); + [&](std::error_code ec, std::size_t /*length*/) + { + control_result = ec; + }); // Try to receive a frame from the server on the new data socket. If we // successfully receive a frame on this new data socket we can consider @@ -101,20 +97,19 @@ int main(int argc, char* argv[]) // socket, which will cause any outstanding receive operation on it to be // cancelled. frame f1; - asio::error_code new_data_socket_result; - new_data_socket->async_receive(f1.to_buffers(), - ( - // Note: lambda::_1 is the first argument to the callback handler, - // which in this case is the error code for the operation. - lambda::var(new_data_socket_result) = lambda::_1, - lambda::if_(!lambda::_1) - [ + std::error_code new_data_socket_result; + new_data_socket.async_receive(f1.to_buffers(), + [&](std::error_code ec, std::size_t /*length*/) + { + new_data_socket_result = ec; + if (!ec) + { // We have successfully received a frame on the new data socket, // so we can close the old data socket. This will cancel any // outstanding receive operation on the old data socket. - lambda::var(data_socket) = boost::shared_ptr() - ] - )); + data_socket.close(); + } + }); // This loop will continue until we have successfully completed the // renegotiation (i.e. received a frame on the new data socket), or some @@ -130,18 +125,19 @@ int main(int argc, char* argv[]) // complete. frame f2; done = true; // Let's be optimistic. - if (data_socket) // Might have been closed by new_data_socket's handler. + if (data_socket.is_open()) // May have been closed by receive handler. { - data_socket->async_receive(f2.to_buffers(), 0, - ( - lambda::if_(!lambda::_1) - [ + data_socket.async_receive(f2.to_buffers(), 0, + [&](std::error_code ec, std::size_t /*length*/) + { + if (!ec) + { // We have successfully received a frame on the old data // socket. Stop the io_context so that we can print it. - lambda::bind(&asio::io_context::stop, &io_context), - lambda::var(done) = false - ] - )); + io_context.stop(); + done = false; + } + }); } // Run the operations in parallel. This will block until all operations @@ -166,15 +162,15 @@ int main(int argc, char* argv[]) // the renegotation, or an error has occurred. First we'll check for // errors. if (control_result) - throw asio::system_error(control_result); + throw std::system_error(control_result); if (new_data_socket_result) - throw asio::system_error(new_data_socket_result); + throw std::system_error(new_data_socket_result); // If we get here it means we have successfully started receiving data on // the new data socket. This new data socket will be used from now on // (until the next time we renegotiate). std::cout << " Renegotiation complete"; - data_socket = new_data_socket; + data_socket = std::move(new_data_socket); data_endpoint = new_data_endpoint; if (f1.number() > last_frame_number) { diff --git a/asio/src/examples/cpp03/porthopper/protocol.hpp b/asio/src/examples/cpp11/porthopper/protocol.hpp similarity index 94% rename from asio/src/examples/cpp03/porthopper/protocol.hpp rename to asio/src/examples/cpp11/porthopper/protocol.hpp index 886ba1c9e6..3ab3ef2416 100644 --- a/asio/src/examples/cpp03/porthopper/protocol.hpp +++ b/asio/src/examples/cpp11/porthopper/protocol.hpp @@ -11,8 +11,8 @@ #ifndef PORTHOPPER_PROTOCOL_HPP #define PORTHOPPER_PROTOCOL_HPP -#include #include +#include #include #include #include @@ -69,9 +69,9 @@ class control_request } // Obtain buffers for reading from or writing to a socket. - boost::array to_buffers() + std::array to_buffers() { - boost::array buffers + std::array buffers = { { asio::buffer(data_) } }; return buffers; } @@ -134,9 +134,9 @@ class frame } // Obtain buffers for reading from or writing to a socket. - boost::array to_buffers() + std::array to_buffers() { - boost::array buffers + std::array buffers = { { asio::buffer(data_) } }; return buffers; } diff --git a/asio/src/examples/cpp03/porthopper/server.cpp b/asio/src/examples/cpp11/porthopper/server.cpp similarity index 85% rename from asio/src/examples/cpp03/porthopper/server.cpp rename to asio/src/examples/cpp11/porthopper/server.cpp index 93291b2380..6fb27bd9ca 100644 --- a/asio/src/examples/cpp03/porthopper/server.cpp +++ b/asio/src/examples/cpp11/porthopper/server.cpp @@ -9,21 +9,21 @@ // #include -#include -#include #include #include #include +#include #include +#include #include #include "protocol.hpp" using asio::ip::tcp; using asio::ip::udp; -typedef boost::shared_ptr tcp_socket_ptr; -typedef boost::shared_ptr timer_ptr; -typedef boost::shared_ptr control_request_ptr; +typedef std::shared_ptr tcp_socket_ptr; +typedef std::shared_ptr timer_ptr; +typedef std::shared_ptr control_request_ptr; class server { @@ -38,35 +38,35 @@ class server // Start waiting for a new control connection. tcp_socket_ptr new_socket(new tcp::socket(acceptor_.get_executor())); acceptor_.async_accept(*new_socket, - boost::bind(&server::handle_accept, this, + std::bind(&server::handle_accept, this, asio::placeholders::error, new_socket)); // Start the timer used to generate outgoing frames. timer_.expires_after(asio::chrono::milliseconds(100)); - timer_.async_wait(boost::bind(&server::handle_timer, this)); + timer_.async_wait(std::bind(&server::handle_timer, this)); } // Handle a new control connection. - void handle_accept(const asio::error_code& ec, tcp_socket_ptr socket) + void handle_accept(const std::error_code& ec, tcp_socket_ptr socket) { if (!ec) { // Start receiving control requests on the connection. control_request_ptr request(new control_request); asio::async_read(*socket, request->to_buffers(), - boost::bind(&server::handle_control_request, this, + std::bind(&server::handle_control_request, this, asio::placeholders::error, socket, request)); } // Start waiting for a new control connection. tcp_socket_ptr new_socket(new tcp::socket(acceptor_.get_executor())); acceptor_.async_accept(*new_socket, - boost::bind(&server::handle_accept, this, + std::bind(&server::handle_accept, this, asio::placeholders::error, new_socket)); } // Handle a new control request. - void handle_control_request(const asio::error_code& ec, + void handle_control_request(const std::error_code& ec, tcp_socket_ptr socket, control_request_ptr request) { if (!ec) @@ -76,7 +76,7 @@ class server new asio::steady_timer(acceptor_.get_executor())); delay_timer->expires_after(asio::chrono::seconds(2)); delay_timer->async_wait( - boost::bind(&server::handle_control_request_timer, this, + std::bind(&server::handle_control_request_timer, this, socket, request, delay_timer)); } } @@ -88,7 +88,7 @@ class server // subscriptions must be stored on the server as a complete endpoint, not // just a port. We use the non-throwing overload of remote_endpoint() since // it may fail if the socket is no longer connected. - asio::error_code ec; + std::error_code ec; tcp::endpoint remote_endpoint = socket->remote_endpoint(ec); if (!ec) { @@ -111,7 +111,7 @@ class server // Wait for next control request on this connection. asio::async_read(*socket, request->to_buffers(), - boost::bind(&server::handle_control_request, this, + std::bind(&server::handle_control_request, this, asio::placeholders::error, socket, request)); } @@ -135,13 +135,13 @@ class server std::set::iterator j; for (j = subscribers_.begin(); j != subscribers_.end(); ++j) { - asio::error_code ec; + std::error_code ec; udp_socket_.send_to(f.to_buffers(), *j, 0, ec); } // Wait for next timeout. timer_.expires_after(asio::chrono::milliseconds(100)); - timer_.async_wait(boost::bind(&server::handle_timer, this)); + timer_.async_wait(std::bind(&server::handle_timer, this)); } private: diff --git a/asio/src/examples/cpp03/serialization/.gitignore b/asio/src/examples/cpp11/serialization/.gitignore similarity index 100% rename from asio/src/examples/cpp03/serialization/.gitignore rename to asio/src/examples/cpp11/serialization/.gitignore diff --git a/asio/src/examples/cpp03/serialization/client.cpp b/asio/src/examples/cpp11/serialization/client.cpp similarity index 96% rename from asio/src/examples/cpp03/serialization/client.cpp rename to asio/src/examples/cpp11/serialization/client.cpp index f2c5837565..a0b6a98c2c 100644 --- a/asio/src/examples/cpp03/serialization/client.cpp +++ b/asio/src/examples/cpp11/serialization/client.cpp @@ -9,7 +9,7 @@ // #include -#include +#include #include #include #include "connection.hpp" // Must come before boost/serialization headers. @@ -35,7 +35,7 @@ class client // Start an asynchronous connect operation. asio::async_connect(connection_.socket(), endpoint_iterator, - boost::bind(&client::handle_connect, this, + std::bind(&client::handle_connect, this, asio::placeholders::error)); } @@ -48,7 +48,7 @@ class client // of stocks. The connection::async_read() function will automatically // decode the data that is read from the underlying socket. connection_.async_read(stocks_, - boost::bind(&client::handle_read, this, + std::bind(&client::handle_read, this, asio::placeholders::error)); } else diff --git a/asio/src/examples/cpp03/serialization/connection.hpp b/asio/src/examples/cpp11/serialization/connection.hpp similarity index 75% rename from asio/src/examples/cpp03/serialization/connection.hpp rename to asio/src/examples/cpp11/serialization/connection.hpp index 397e84f08e..d7e430a29a 100644 --- a/asio/src/examples/cpp03/serialization/connection.hpp +++ b/asio/src/examples/cpp11/serialization/connection.hpp @@ -14,12 +14,12 @@ #include #include #include -#include -#include -#include +#include #include +#include #include #include +#include #include namespace s11n_example { @@ -35,7 +35,7 @@ class connection { public: /// Constructor. - connection(const asio::executor& ex) + connection(const asio::any_io_executor& ex) : socket_(ex) { } @@ -64,8 +64,8 @@ class connection if (!header_stream || header_stream.str().size() != header_length) { // Something went wrong, inform the caller. - asio::error_code error(asio::error::invalid_argument); - asio::post(socket_.get_executor(), boost::bind(handler, error)); + std::error_code error(asio::error::invalid_argument); + asio::post(socket_.get_executor(), std::bind(handler, error)); return; } outbound_header_ = header_stream.str(); @@ -83,26 +83,22 @@ class connection void async_read(T& t, Handler handler) { // Issue a read operation to read exactly the number of bytes in a header. - void (connection::*f)( - const asio::error_code&, - T&, boost::tuple) + void (connection::*f)(const std::error_code&, T&, std::tuple) = &connection::handle_read_header; asio::async_read(socket_, asio::buffer(inbound_header_), - boost::bind(f, - this, asio::placeholders::error, boost::ref(t), - boost::make_tuple(handler))); + std::bind(f, + this, asio::placeholders::error, std::ref(t), + std::make_tuple(handler))); } - /// Handle a completed read of a message header. The handler is passed using - /// a tuple since boost::bind seems to have trouble binding a function object - /// created using boost::bind as a parameter. + /// Handle a completed read of a message header. template - void handle_read_header(const asio::error_code& e, - T& t, boost::tuple handler) + void handle_read_header(const std::error_code& e, + T& t, std::tuple handler) { if (e) { - boost::get<0>(handler)(e); + std::get<0>(handler)(e); } else { @@ -112,31 +108,31 @@ class connection if (!(is >> std::hex >> inbound_data_size)) { // Header doesn't seem to be valid. Inform the caller. - asio::error_code error(asio::error::invalid_argument); - boost::get<0>(handler)(error); + std::error_code error(asio::error::invalid_argument); + std::get<0>(handler)(error); return; } // Start an asynchronous call to receive the data. inbound_data_.resize(inbound_data_size); void (connection::*f)( - const asio::error_code&, - T&, boost::tuple) + const std::error_code&, + T&, std::tuple) = &connection::handle_read_data; asio::async_read(socket_, asio::buffer(inbound_data_), - boost::bind(f, this, - asio::placeholders::error, boost::ref(t), handler)); + std::bind(f, this, + asio::placeholders::error, std::ref(t), handler)); } } /// Handle a completed read of message data. template - void handle_read_data(const asio::error_code& e, - T& t, boost::tuple handler) + void handle_read_data(const std::error_code& e, + T& t, std::tuple handler) { if (e) { - boost::get<0>(handler)(e); + std::get<0>(handler)(e); } else { @@ -151,13 +147,13 @@ class connection catch (std::exception& e) { // Unable to decode data. - asio::error_code error(asio::error::invalid_argument); - boost::get<0>(handler)(error); + std::error_code error(asio::error::invalid_argument); + std::get<0>(handler)(error); return; } // Inform caller that data has been received ok. - boost::get<0>(handler)(e); + std::get<0>(handler)(e); } } @@ -181,7 +177,7 @@ class connection std::vector inbound_data_; }; -typedef boost::shared_ptr connection_ptr; +typedef std::shared_ptr connection_ptr; } // namespace s11n_example diff --git a/asio/src/examples/cpp03/serialization/server.cpp b/asio/src/examples/cpp11/serialization/server.cpp similarity index 88% rename from asio/src/examples/cpp03/serialization/server.cpp rename to asio/src/examples/cpp11/serialization/server.cpp index 78fa475cbb..9e4c30706e 100644 --- a/asio/src/examples/cpp03/serialization/server.cpp +++ b/asio/src/examples/cpp11/serialization/server.cpp @@ -9,8 +9,7 @@ // #include -#include -#include +#include #include #include #include "connection.hpp" // Must come before boost/serialization headers. @@ -57,12 +56,12 @@ class server // Start an accept operation for a new connection. connection_ptr new_conn(new connection(acceptor_.get_executor())); acceptor_.async_accept(new_conn->socket(), - boost::bind(&server::handle_accept, this, + std::bind(&server::handle_accept, this, asio::placeholders::error, new_conn)); } /// Handle completion of a accept operation. - void handle_accept(const asio::error_code& e, connection_ptr conn) + void handle_accept(const std::error_code& e, connection_ptr conn) { if (!e) { @@ -70,19 +69,19 @@ class server // client. The connection::async_write() function will automatically // serialize the data structure for us. conn->async_write(stocks_, - boost::bind(&server::handle_write, this, + std::bind(&server::handle_write, this, asio::placeholders::error, conn)); } // Start an accept operation for a new connection. connection_ptr new_conn(new connection(acceptor_.get_executor())); acceptor_.async_accept(new_conn->socket(), - boost::bind(&server::handle_accept, this, + std::bind(&server::handle_accept, this, asio::placeholders::error, new_conn)); } /// Handle completion of a write operation. - void handle_write(const asio::error_code& e, connection_ptr conn) + void handle_write(const std::error_code& e, connection_ptr conn) { // Nothing to do. The socket will be closed automatically when the last // reference to the connection object goes away. @@ -108,7 +107,7 @@ int main(int argc, char* argv[]) std::cerr << "Usage: server " << std::endl; return 1; } - unsigned short port = boost::lexical_cast(argv[1]); + unsigned short port = std::stoi(argv[1]); asio::io_context io_context; s11n_example::server server(io_context, port); diff --git a/asio/src/examples/cpp03/serialization/stock.hpp b/asio/src/examples/cpp11/serialization/stock.hpp similarity index 100% rename from asio/src/examples/cpp03/serialization/stock.hpp rename to asio/src/examples/cpp11/serialization/stock.hpp diff --git a/asio/src/examples/cpp03/services/.gitignore b/asio/src/examples/cpp11/services/.gitignore similarity index 100% rename from asio/src/examples/cpp03/services/.gitignore rename to asio/src/examples/cpp11/services/.gitignore diff --git a/asio/src/examples/cpp03/services/basic_logger.hpp b/asio/src/examples/cpp11/services/basic_logger.hpp similarity index 94% rename from asio/src/examples/cpp03/services/basic_logger.hpp rename to asio/src/examples/cpp11/services/basic_logger.hpp index 7117868c2b..08cda1dee2 100644 --- a/asio/src/examples/cpp03/services/basic_logger.hpp +++ b/asio/src/examples/cpp11/services/basic_logger.hpp @@ -12,7 +12,6 @@ #define SERVICES_BASIC_LOGGER_HPP #include -#include #include namespace services { @@ -21,7 +20,6 @@ namespace services { /// typedef. template class basic_logger - : private boost::noncopyable { public: /// The type of the service that will be used to provide timer operations. @@ -46,6 +44,9 @@ class basic_logger service_.create(impl_, identifier); } + basic_logger(const basic_logger&) = delete; + basic_logger& operator=(basic_logger&) = delete; + /// Destructor. ~basic_logger() { diff --git a/asio/src/examples/cpp03/services/daytime_client.cpp b/asio/src/examples/cpp11/services/daytime_client.cpp similarity index 92% rename from asio/src/examples/cpp03/services/daytime_client.cpp rename to asio/src/examples/cpp11/services/daytime_client.cpp index 7d41731902..00089e667f 100644 --- a/asio/src/examples/cpp03/services/daytime_client.cpp +++ b/asio/src/examples/cpp11/services/daytime_client.cpp @@ -9,7 +9,7 @@ // #include -#include +#include #include #include "logger.hpp" @@ -25,7 +25,7 @@ void read_handler(const asio::error_code& e, std::cout.write(read_buffer, bytes_transferred); s->async_read_some(asio::buffer(read_buffer), - boost::bind(read_handler, asio::placeholders::error, + std::bind(read_handler, asio::placeholders::error, asio::placeholders::bytes_transferred, s)); } else @@ -51,7 +51,7 @@ void connect_handler(const asio::error_code& e, tcp::socket* s) logger.log("Connection established"); s->async_read_some(asio::buffer(read_buffer), - boost::bind(read_handler, asio::placeholders::error, + std::bind(read_handler, asio::placeholders::error, asio::placeholders::bytes_transferred, s)); } else @@ -86,7 +86,7 @@ int main(int argc, char* argv[]) // Start an asynchronous connect. tcp::socket socket(io_context); asio::async_connect(socket, endpoints, - boost::bind(connect_handler, + std::bind(connect_handler, asio::placeholders::error, &socket)); // Run the io_context until all operations have finished. diff --git a/asio/src/examples/cpp03/services/logger.hpp b/asio/src/examples/cpp11/services/logger.hpp similarity index 100% rename from asio/src/examples/cpp03/services/logger.hpp rename to asio/src/examples/cpp11/services/logger.hpp diff --git a/asio/src/examples/cpp03/services/logger_service.cpp b/asio/src/examples/cpp11/services/logger_service.cpp similarity index 100% rename from asio/src/examples/cpp03/services/logger_service.cpp rename to asio/src/examples/cpp11/services/logger_service.cpp diff --git a/asio/src/examples/cpp03/services/logger_service.hpp b/asio/src/examples/cpp11/services/logger_service.hpp similarity index 86% rename from asio/src/examples/cpp03/services/logger_service.hpp rename to asio/src/examples/cpp11/services/logger_service.hpp index e38cb1a727..82c4446a70 100644 --- a/asio/src/examples/cpp03/services/logger_service.hpp +++ b/asio/src/examples/cpp11/services/logger_service.hpp @@ -12,13 +12,11 @@ #define SERVICES_LOGGER_SERVICE_HPP #include -#include -#include -#include -#include +#include #include #include #include +#include namespace services { @@ -45,19 +43,21 @@ class logger_service : asio::execution_context::service(context), work_io_context_(), work_(asio::make_work_guard(work_io_context_)), - work_thread_(new asio::thread( - boost::bind(&asio::io_context::run, &work_io_context_))) + work_thread_([this]{ work_io_context_.run(); }) { } + logger_service(const logger_service&) = delete; + logger_service& operator=(const logger_service&) = delete;; + /// Destructor shuts down the private io_context. ~logger_service() { /// Indicate that we have finished with the private io_context. Its /// io_context::run() function will exit once all other work has completed. work_.reset(); - if (work_thread_) - work_thread_->join(); + if (work_thread_.joinable()) + work_thread_.join(); } /// Destroy all user-defined handler objects owned by the service. @@ -91,8 +91,8 @@ class logger_service void use_file(impl_type& /*impl*/, const std::string& file) { // Pass the work of opening the file to the background thread. - asio::post(work_io_context_, boost::bind( - &logger_service::use_file_impl, this, file)); + asio::post(work_io_context_, + std::bind(&logger_service::use_file_impl, this, file)); } /// Log a message. @@ -103,8 +103,8 @@ class logger_service os << impl->identifier << ": " << message; // Pass the work of writing to the file to the background thread. - asio::post(work_io_context_, boost::bind( - &logger_service::log_impl, this, os.str())); + asio::post(work_io_context_, + std::bind(&logger_service::log_impl, this, os.str())); } private: @@ -134,7 +134,7 @@ class logger_service asio::io_context::executor_type> work_; /// Thread used for running the work io_context's run loop. - boost::scoped_ptr work_thread_; + std::thread work_thread_; /// The file to which log messages will be written. std::ofstream ofstream_; diff --git a/asio/src/examples/cpp11/socks4/socks4.hpp b/asio/src/examples/cpp11/socks4/socks4.hpp index aae2063687..a318322865 100644 --- a/asio/src/examples/cpp11/socks4/socks4.hpp +++ b/asio/src/examples/cpp11/socks4/socks4.hpp @@ -39,7 +39,7 @@ class request // Only IPv4 is supported by the SOCKS 4 protocol. if (endpoint.protocol() != asio::ip::tcp::v4()) { - throw asio::system_error( + throw std::system_error( asio::error::address_family_not_supported); } diff --git a/asio/src/examples/cpp11/spawn/echo_server.cpp b/asio/src/examples/cpp11/spawn/echo_server.cpp index b90380a993..5a094825c6 100644 --- a/asio/src/examples/cpp11/spawn/echo_server.cpp +++ b/asio/src/examples/cpp11/spawn/echo_server.cpp @@ -57,7 +57,7 @@ class session : public std::enable_shared_from_this { while (socket_.is_open()) { - asio::error_code ignored_ec; + std::error_code ignored_ec; timer_.async_wait(yield[ignored_ec]); if (timer_.expiry() <= asio::steady_timer::clock_type::now()) socket_.close(); @@ -91,7 +91,7 @@ int main(int argc, char* argv[]) for (;;) { - asio::error_code ec; + std::error_code ec; tcp::socket socket(io_context); acceptor.async_accept(socket, yield[ec]); if (!ec) diff --git a/asio/src/examples/cpp03/tutorial/daytime1/.gitignore b/asio/src/examples/cpp11/tutorial/daytime1/.gitignore similarity index 100% rename from asio/src/examples/cpp03/tutorial/daytime1/.gitignore rename to asio/src/examples/cpp11/tutorial/daytime1/.gitignore diff --git a/asio/src/examples/cpp03/tutorial/daytime1/client.cpp b/asio/src/examples/cpp11/tutorial/daytime1/client.cpp similarity index 87% rename from asio/src/examples/cpp03/tutorial/daytime1/client.cpp rename to asio/src/examples/cpp11/tutorial/daytime1/client.cpp index 57c6dacccc..bea3f6e20c 100644 --- a/asio/src/examples/cpp03/tutorial/daytime1/client.cpp +++ b/asio/src/examples/cpp11/tutorial/daytime1/client.cpp @@ -8,8 +8,8 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // +#include #include -#include #include using asio::ip::tcp; @@ -35,15 +35,15 @@ int main(int argc, char* argv[]) for (;;) { - boost::array buf; - asio::error_code error; + std::array buf; + std::error_code error; size_t len = socket.read_some(asio::buffer(buf), error); if (error == asio::error::eof) break; // Connection closed cleanly by peer. else if (error) - throw asio::system_error(error); // Some other error. + throw std::system_error(error); // Some other error. std::cout.write(buf.data(), len); } diff --git a/asio/src/examples/cpp03/tutorial/daytime2/.gitignore b/asio/src/examples/cpp11/tutorial/daytime2/.gitignore similarity index 100% rename from asio/src/examples/cpp03/tutorial/daytime2/.gitignore rename to asio/src/examples/cpp11/tutorial/daytime2/.gitignore diff --git a/asio/src/examples/cpp03/tutorial/daytime2/server.cpp b/asio/src/examples/cpp11/tutorial/daytime2/server.cpp similarity index 96% rename from asio/src/examples/cpp03/tutorial/daytime2/server.cpp rename to asio/src/examples/cpp11/tutorial/daytime2/server.cpp index 0304136784..4058ec4ff4 100644 --- a/asio/src/examples/cpp03/tutorial/daytime2/server.cpp +++ b/asio/src/examples/cpp11/tutorial/daytime2/server.cpp @@ -37,7 +37,7 @@ int main() std::string message = make_daytime_string(); - asio::error_code ignored_error; + std::error_code ignored_error; asio::write(socket, asio::buffer(message), ignored_error); } } diff --git a/asio/src/examples/cpp03/tutorial/daytime3/.gitignore b/asio/src/examples/cpp11/tutorial/daytime3/.gitignore similarity index 100% rename from asio/src/examples/cpp03/tutorial/daytime3/.gitignore rename to asio/src/examples/cpp11/tutorial/daytime3/.gitignore diff --git a/asio/src/examples/cpp03/tutorial/daytime3/server.cpp b/asio/src/examples/cpp11/tutorial/daytime3/server.cpp similarity index 81% rename from asio/src/examples/cpp03/tutorial/daytime3/server.cpp rename to asio/src/examples/cpp11/tutorial/daytime3/server.cpp index f3258ded2b..c0f88e2039 100644 --- a/asio/src/examples/cpp03/tutorial/daytime3/server.cpp +++ b/asio/src/examples/cpp11/tutorial/daytime3/server.cpp @@ -9,11 +9,10 @@ // #include +#include #include +#include #include -#include -#include -#include #include using asio::ip::tcp; @@ -26,10 +25,10 @@ std::string make_daytime_string() } class tcp_connection - : public boost::enable_shared_from_this + : public std::enable_shared_from_this { public: - typedef boost::shared_ptr pointer; + typedef std::shared_ptr pointer; static pointer create(asio::io_context& io_context) { @@ -46,7 +45,7 @@ class tcp_connection message_ = make_daytime_string(); asio::async_write(socket_, asio::buffer(message_), - boost::bind(&tcp_connection::handle_write, shared_from_this(), + std::bind(&tcp_connection::handle_write, shared_from_this(), asio::placeholders::error, asio::placeholders::bytes_transferred)); } @@ -57,7 +56,7 @@ class tcp_connection { } - void handle_write(const asio::error_code& /*error*/, + void handle_write(const std::error_code& /*error*/, size_t /*bytes_transferred*/) { } @@ -83,12 +82,12 @@ class tcp_server tcp_connection::create(io_context_); acceptor_.async_accept(new_connection->socket(), - boost::bind(&tcp_server::handle_accept, this, new_connection, + std::bind(&tcp_server::handle_accept, this, new_connection, asio::placeholders::error)); } void handle_accept(tcp_connection::pointer new_connection, - const asio::error_code& error) + const std::error_code& error) { if (!error) { diff --git a/asio/src/examples/cpp03/tutorial/daytime4/.gitignore b/asio/src/examples/cpp11/tutorial/daytime4/.gitignore similarity index 100% rename from asio/src/examples/cpp03/tutorial/daytime4/.gitignore rename to asio/src/examples/cpp11/tutorial/daytime4/.gitignore diff --git a/asio/src/examples/cpp03/tutorial/daytime4/client.cpp b/asio/src/examples/cpp11/tutorial/daytime4/client.cpp similarity index 90% rename from asio/src/examples/cpp03/tutorial/daytime4/client.cpp rename to asio/src/examples/cpp11/tutorial/daytime4/client.cpp index 5609abdede..76d6c702e2 100644 --- a/asio/src/examples/cpp03/tutorial/daytime4/client.cpp +++ b/asio/src/examples/cpp11/tutorial/daytime4/client.cpp @@ -8,8 +8,8 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // +#include #include -#include #include using asio::ip::udp; @@ -33,10 +33,10 @@ int main(int argc, char* argv[]) udp::socket socket(io_context); socket.open(udp::v4()); - boost::array send_buf = {{ 0 }}; + std::array send_buf = {{ 0 }}; socket.send_to(asio::buffer(send_buf), receiver_endpoint); - boost::array recv_buf; + std::array recv_buf; udp::endpoint sender_endpoint; size_t len = socket.receive_from( asio::buffer(recv_buf), sender_endpoint); diff --git a/asio/src/examples/cpp03/tutorial/daytime5/.gitignore b/asio/src/examples/cpp11/tutorial/daytime5/.gitignore similarity index 100% rename from asio/src/examples/cpp03/tutorial/daytime5/.gitignore rename to asio/src/examples/cpp11/tutorial/daytime5/.gitignore diff --git a/asio/src/examples/cpp03/tutorial/daytime5/server.cpp b/asio/src/examples/cpp11/tutorial/daytime5/server.cpp similarity index 90% rename from asio/src/examples/cpp03/tutorial/daytime5/server.cpp rename to asio/src/examples/cpp11/tutorial/daytime5/server.cpp index 46d30db88e..8b4326fb02 100644 --- a/asio/src/examples/cpp03/tutorial/daytime5/server.cpp +++ b/asio/src/examples/cpp11/tutorial/daytime5/server.cpp @@ -8,10 +8,10 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // +#include #include #include #include -#include #include using asio::ip::udp; @@ -33,13 +33,13 @@ int main() for (;;) { - boost::array recv_buf; + std::array recv_buf; udp::endpoint remote_endpoint; socket.receive_from(asio::buffer(recv_buf), remote_endpoint); std::string message = make_daytime_string(); - asio::error_code ignored_error; + std::error_code ignored_error; socket.send_to(asio::buffer(message), remote_endpoint, 0, ignored_error); } diff --git a/asio/src/examples/cpp03/tutorial/daytime6/.gitignore b/asio/src/examples/cpp11/tutorial/daytime6/.gitignore similarity index 100% rename from asio/src/examples/cpp03/tutorial/daytime6/.gitignore rename to asio/src/examples/cpp11/tutorial/daytime6/.gitignore diff --git a/asio/src/examples/cpp03/tutorial/daytime6/server.cpp b/asio/src/examples/cpp11/tutorial/daytime6/server.cpp similarity index 77% rename from asio/src/examples/cpp03/tutorial/daytime6/server.cpp rename to asio/src/examples/cpp11/tutorial/daytime6/server.cpp index f1f1c793f6..0c03d033e1 100644 --- a/asio/src/examples/cpp03/tutorial/daytime6/server.cpp +++ b/asio/src/examples/cpp11/tutorial/daytime6/server.cpp @@ -8,12 +8,12 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // +#include #include +#include #include +#include #include -#include -#include -#include #include using asio::ip::udp; @@ -39,21 +39,21 @@ class udp_server { socket_.async_receive_from( asio::buffer(recv_buffer_), remote_endpoint_, - boost::bind(&udp_server::handle_receive, this, + std::bind(&udp_server::handle_receive, this, asio::placeholders::error, asio::placeholders::bytes_transferred)); } - void handle_receive(const asio::error_code& error, + void handle_receive(const std::error_code& error, std::size_t /*bytes_transferred*/) { if (!error) { - boost::shared_ptr message( + std::shared_ptr message( new std::string(make_daytime_string())); socket_.async_send_to(asio::buffer(*message), remote_endpoint_, - boost::bind(&udp_server::handle_send, this, message, + std::bind(&udp_server::handle_send, this, message, asio::placeholders::error, asio::placeholders::bytes_transferred)); @@ -61,15 +61,15 @@ class udp_server } } - void handle_send(boost::shared_ptr /*message*/, - const asio::error_code& /*error*/, + void handle_send(std::shared_ptr /*message*/, + const std::error_code& /*error*/, std::size_t /*bytes_transferred*/) { } udp::socket socket_; udp::endpoint remote_endpoint_; - boost::array recv_buffer_; + std::array recv_buffer_; }; int main() diff --git a/asio/src/examples/cpp03/tutorial/daytime7/.gitignore b/asio/src/examples/cpp11/tutorial/daytime7/.gitignore similarity index 100% rename from asio/src/examples/cpp03/tutorial/daytime7/.gitignore rename to asio/src/examples/cpp11/tutorial/daytime7/.gitignore diff --git a/asio/src/examples/cpp03/tutorial/daytime7/server.cpp b/asio/src/examples/cpp11/tutorial/daytime7/server.cpp similarity index 76% rename from asio/src/examples/cpp03/tutorial/daytime7/server.cpp rename to asio/src/examples/cpp11/tutorial/daytime7/server.cpp index 22ef564b8b..23282dcf5f 100644 --- a/asio/src/examples/cpp03/tutorial/daytime7/server.cpp +++ b/asio/src/examples/cpp11/tutorial/daytime7/server.cpp @@ -8,13 +8,12 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // +#include #include +#include #include +#include #include -#include -#include -#include -#include #include using asio::ip::tcp; @@ -28,10 +27,10 @@ std::string make_daytime_string() } class tcp_connection - : public boost::enable_shared_from_this + : public std::enable_shared_from_this { public: - typedef boost::shared_ptr pointer; + typedef std::shared_ptr pointer; static pointer create(asio::io_context& io_context) { @@ -48,7 +47,7 @@ class tcp_connection message_ = make_daytime_string(); asio::async_write(socket_, asio::buffer(message_), - boost::bind(&tcp_connection::handle_write, shared_from_this())); + std::bind(&tcp_connection::handle_write, shared_from_this())); } private: @@ -82,12 +81,12 @@ class tcp_server tcp_connection::create(io_context_); acceptor_.async_accept(new_connection->socket(), - boost::bind(&tcp_server::handle_accept, this, new_connection, + std::bind(&tcp_server::handle_accept, this, new_connection, asio::placeholders::error)); } void handle_accept(tcp_connection::pointer new_connection, - const asio::error_code& error) + const std::error_code& error) { if (!error) { @@ -115,31 +114,31 @@ class udp_server { socket_.async_receive_from( asio::buffer(recv_buffer_), remote_endpoint_, - boost::bind(&udp_server::handle_receive, this, + std::bind(&udp_server::handle_receive, this, asio::placeholders::error)); } - void handle_receive(const asio::error_code& error) + void handle_receive(const std::error_code& error) { if (!error) { - boost::shared_ptr message( + std::shared_ptr message( new std::string(make_daytime_string())); socket_.async_send_to(asio::buffer(*message), remote_endpoint_, - boost::bind(&udp_server::handle_send, this, message)); + std::bind(&udp_server::handle_send, this, message)); start_receive(); } } - void handle_send(boost::shared_ptr /*message*/) + void handle_send(std::shared_ptr /*message*/) { } udp::socket socket_; udp::endpoint remote_endpoint_; - boost::array recv_buffer_; + std::array recv_buffer_; }; int main() diff --git a/asio/src/examples/cpp03/tutorial/daytime_dox.txt b/asio/src/examples/cpp11/tutorial/daytime_dox.txt similarity index 96% rename from asio/src/examples/cpp03/tutorial/daytime_dox.txt rename to asio/src/examples/cpp11/tutorial/daytime_dox.txt index c2cc0579f7..62e98f6c02 100644 --- a/asio/src/examples/cpp03/tutorial/daytime_dox.txt +++ b/asio/src/examples/cpp11/tutorial/daytime_dox.txt @@ -54,9 +54,9 @@ version. The asio::connect() function does this for us automatically. The connection is open. All we need to do now is read the response from the daytime service. -We use a boost::array to hold the received data. The asio::buffer() +We use a std::array to hold the received data. The asio::buffer() function automatically determines the size of the array to help prevent buffer -overruns. Instead of a boost::array, we could have used a char +overruns. Instead of a std::array, we could have used a char [] or std::vector. \until read_some @@ -205,7 +205,7 @@ to keep the data valid until the asynchronous operation is complete. \until message_ -When initiating the asynchronous operation, and if using \ref boost_bind, you +When initiating the asynchronous operation, and if using @c std::bind, you must specify only the arguments that match the handler's parameter list. In this program, both of the argument placeholders (asio::placeholders::error and asio::placeholders::bytes_transferred) could potentially have been removed, @@ -236,7 +236,7 @@ just: \code asio::async_write(socket_, asio::buffer(message_), - boost::bind(&tcp_connection::handle_write, shared_from_this())); + std::bind(&tcp_connection::handle_write, shared_from_this())); \endcode See the \ref tutdaytime3src "full source listing" \n @@ -382,7 +382,7 @@ The function asio::ip::udp::socket::async_receive_from() will cause the application to listen in the background for a new request. When such a request is received, the asio::io_context object will invoke the handle_receive() function with two arguments: a value of type -asio::error_code indicating whether the operation succeeded or failed, and a +std::error_code indicating whether the operation succeeded or failed, and a size_t value bytes_transferred specifying the number of bytes received. @@ -408,7 +408,7 @@ client. \until asio::placeholders::bytes_transferred -When initiating the asynchronous operation, and if using \ref boost_bind, you +When initiating the asynchronous operation, and if using @c std::bind, you must specify only the arguments that match the handler's parameter list. In this program, both of the argument placeholders (asio::placeholders::error and asio::placeholders::bytes_transferred) could potentially have been removed. diff --git a/asio/src/examples/cpp03/tutorial/index_dox.txt b/asio/src/examples/cpp11/tutorial/index_dox.txt similarity index 100% rename from asio/src/examples/cpp03/tutorial/index_dox.txt rename to asio/src/examples/cpp11/tutorial/index_dox.txt diff --git a/asio/src/examples/cpp03/tutorial/timer1/.gitignore b/asio/src/examples/cpp11/tutorial/timer1/.gitignore similarity index 100% rename from asio/src/examples/cpp03/tutorial/timer1/.gitignore rename to asio/src/examples/cpp11/tutorial/timer1/.gitignore diff --git a/asio/src/examples/cpp03/tutorial/timer1/timer.cpp b/asio/src/examples/cpp11/tutorial/timer1/timer.cpp similarity index 100% rename from asio/src/examples/cpp03/tutorial/timer1/timer.cpp rename to asio/src/examples/cpp11/tutorial/timer1/timer.cpp diff --git a/asio/src/examples/cpp03/tutorial/timer2/.gitignore b/asio/src/examples/cpp11/tutorial/timer2/.gitignore similarity index 100% rename from asio/src/examples/cpp03/tutorial/timer2/.gitignore rename to asio/src/examples/cpp11/tutorial/timer2/.gitignore diff --git a/asio/src/examples/cpp03/tutorial/timer2/timer.cpp b/asio/src/examples/cpp11/tutorial/timer2/timer.cpp similarity index 92% rename from asio/src/examples/cpp03/tutorial/timer2/timer.cpp rename to asio/src/examples/cpp11/tutorial/timer2/timer.cpp index 27319d03cc..456176e811 100644 --- a/asio/src/examples/cpp03/tutorial/timer2/timer.cpp +++ b/asio/src/examples/cpp11/tutorial/timer2/timer.cpp @@ -11,7 +11,7 @@ #include #include -void print(const asio::error_code& /*e*/) +void print(const std::error_code& /*e*/) { std::cout << "Hello, world!" << std::endl; } diff --git a/asio/src/examples/cpp03/tutorial/timer3/.gitignore b/asio/src/examples/cpp11/tutorial/timer3/.gitignore similarity index 100% rename from asio/src/examples/cpp03/tutorial/timer3/.gitignore rename to asio/src/examples/cpp11/tutorial/timer3/.gitignore diff --git a/asio/src/examples/cpp03/tutorial/timer3/timer.cpp b/asio/src/examples/cpp11/tutorial/timer3/timer.cpp similarity index 84% rename from asio/src/examples/cpp03/tutorial/timer3/timer.cpp rename to asio/src/examples/cpp11/tutorial/timer3/timer.cpp index dcf1425767..bfb0e61fb1 100644 --- a/asio/src/examples/cpp03/tutorial/timer3/timer.cpp +++ b/asio/src/examples/cpp11/tutorial/timer3/timer.cpp @@ -8,11 +8,11 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // +#include #include #include -#include -void print(const asio::error_code& /*e*/, +void print(const std::error_code& /*e*/, asio::steady_timer* t, int* count) { if (*count < 5) @@ -21,7 +21,7 @@ void print(const asio::error_code& /*e*/, ++(*count); t->expires_at(t->expiry() + asio::chrono::seconds(1)); - t->async_wait(boost::bind(print, + t->async_wait(std::bind(print, asio::placeholders::error, t, count)); } } @@ -32,7 +32,7 @@ int main() int count = 0; asio::steady_timer t(io, asio::chrono::seconds(1)); - t.async_wait(boost::bind(print, + t.async_wait(std::bind(print, asio::placeholders::error, &t, &count)); io.run(); diff --git a/asio/src/examples/cpp03/tutorial/timer4/.gitignore b/asio/src/examples/cpp11/tutorial/timer4/.gitignore similarity index 100% rename from asio/src/examples/cpp03/tutorial/timer4/.gitignore rename to asio/src/examples/cpp11/tutorial/timer4/.gitignore diff --git a/asio/src/examples/cpp03/tutorial/timer4/timer.cpp b/asio/src/examples/cpp11/tutorial/timer4/timer.cpp similarity index 84% rename from asio/src/examples/cpp03/tutorial/timer4/timer.cpp rename to asio/src/examples/cpp11/tutorial/timer4/timer.cpp index 6ef81f59ea..acdc4c349f 100644 --- a/asio/src/examples/cpp03/tutorial/timer4/timer.cpp +++ b/asio/src/examples/cpp11/tutorial/timer4/timer.cpp @@ -8,9 +8,9 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // +#include #include #include -#include class printer { @@ -19,7 +19,7 @@ class printer : timer_(io, asio::chrono::seconds(1)), count_(0) { - timer_.async_wait(boost::bind(&printer::print, this)); + timer_.async_wait(std::bind(&printer::print, this)); } ~printer() @@ -35,7 +35,7 @@ class printer ++count_; timer_.expires_at(timer_.expiry() + asio::chrono::seconds(1)); - timer_.async_wait(boost::bind(&printer::print, this)); + timer_.async_wait(std::bind(&printer::print, this)); } } diff --git a/asio/src/examples/cpp03/tutorial/timer5/.gitignore b/asio/src/examples/cpp11/tutorial/timer5/.gitignore similarity index 100% rename from asio/src/examples/cpp03/tutorial/timer5/.gitignore rename to asio/src/examples/cpp11/tutorial/timer5/.gitignore diff --git a/asio/src/examples/cpp03/tutorial/timer5/timer.cpp b/asio/src/examples/cpp11/tutorial/timer5/timer.cpp similarity index 83% rename from asio/src/examples/cpp03/tutorial/timer5/timer.cpp rename to asio/src/examples/cpp11/tutorial/timer5/timer.cpp index f4f1f7172a..4470ec0ccc 100644 --- a/asio/src/examples/cpp03/tutorial/timer5/timer.cpp +++ b/asio/src/examples/cpp11/tutorial/timer5/timer.cpp @@ -8,9 +8,10 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // +#include #include +#include #include -#include class printer { @@ -22,10 +23,10 @@ class printer count_(0) { timer1_.async_wait(asio::bind_executor(strand_, - boost::bind(&printer::print1, this))); + std::bind(&printer::print1, this))); timer2_.async_wait(asio::bind_executor(strand_, - boost::bind(&printer::print2, this))); + std::bind(&printer::print2, this))); } ~printer() @@ -43,7 +44,7 @@ class printer timer1_.expires_at(timer1_.expiry() + asio::chrono::seconds(1)); timer1_.async_wait(asio::bind_executor(strand_, - boost::bind(&printer::print1, this))); + std::bind(&printer::print1, this))); } } @@ -57,7 +58,7 @@ class printer timer2_.expires_at(timer2_.expiry() + asio::chrono::seconds(1)); timer2_.async_wait(asio::bind_executor(strand_, - boost::bind(&printer::print2, this))); + std::bind(&printer::print2, this))); } } @@ -72,7 +73,7 @@ int main() { asio::io_context io; printer p(io); - asio::thread t(boost::bind(&asio::io_context::run, &io)); + std::thread t([&]{ io.run(); }); io.run(); t.join(); diff --git a/asio/src/examples/cpp03/tutorial/timer_dox.txt b/asio/src/examples/cpp11/tutorial/timer_dox.txt similarity index 95% rename from asio/src/examples/cpp03/tutorial/timer_dox.txt rename to asio/src/examples/cpp11/tutorial/timer_dox.txt index 0ac88efc6d..778e94dbec 100644 --- a/asio/src/examples/cpp03/tutorial/timer_dox.txt +++ b/asio/src/examples/cpp11/tutorial/timer_dox.txt @@ -136,7 +136,7 @@ your handler function. \dontinclude timer3/timer.cpp \skip #include -\until bind.hpp +\until asio.hpp To implement a repeating timer using asio you need to change the timer's expiry time in your completion handler, and to then start a new @@ -171,19 +171,16 @@ whole-second mark due to any delays in processing the handler. \until expires_at Then we start a new asynchronous wait on the timer. As you can -see, the \ref boost_bind function is used to associate the extra parameters +see, the @c std::bind function is used to associate the extra parameters with your completion handler. The asio::steady_timer::async_wait() function expects a handler function (or function object) with the signature -void(const asio::error_code&). Binding the additional parameters +void(const std::error_code&). Binding the additional parameters converts your print function into a function object that matches the signature correctly. -See the Boost.Bind -documentation for more information on how to use \ref boost_bind. - -In this example, the asio::placeholders::error argument to \ref boost_bind is a +In this example, the asio::placeholders::error argument to @c std::bind is a named placeholder for the error object passed to the handler. When initiating -the asynchronous operation, and if using \ref boost_bind, you must specify only +the asynchronous operation, and if using @c std::bind, you must specify only the arguments that match the handler's parameter list. In tutorial Timer.4 you will see that this placeholder may be elided if the parameter is not needed by the completion handler. @@ -230,7 +227,7 @@ tutorial Timer.3. \dontinclude timer4/timer.cpp \skip #include -\until bind.hpp +\until asio.hpp Instead of defining a free function print as the completion handler, as we did in the earlier tutorial programs, we now define a @@ -244,13 +241,13 @@ counter used to shut down the program is now also a member of the class. \until { -The \ref boost_bind function works just as well with class +The @c std::bind function works just as well with class member functions as with free functions. Since all non-static class member functions have an implicit this parameter, we need to bind -this to the function. As in tutorial Timer.3, \ref boost_bind +this to the function. As in tutorial Timer.3, @c std::bind converts our completion handler (now a member function) into a function object that can be invoked as though it has the signature void(const -asio::error_code&). +std::error_code&). You will note that the asio::placeholders::error placeholder is not specified here, as the print member function does not accept an error object as @@ -319,7 +316,7 @@ when handlers might be accessing a shared, thread-unsafe resource. \dontinclude timer5/timer.cpp \skip #include -\until bind.hpp +\until asio.hpp We start by defining a class called printer, similar to the class in the previous tutorial. This class will extend the previous diff --git a/asio/src/examples/cpp11/type_erasure/line_reader.hpp b/asio/src/examples/cpp11/type_erasure/line_reader.hpp index 6e95a8b699..4286a6265d 100644 --- a/asio/src/examples/cpp11/type_erasure/line_reader.hpp +++ b/asio/src/examples/cpp11/type_erasure/line_reader.hpp @@ -20,7 +20,7 @@ class line_reader { private: virtual void async_read_line_impl(std::string prompt, - asio::any_completion_handler handler) = 0; + asio::any_completion_handler handler) = 0; struct initiate_read_line { @@ -37,10 +37,10 @@ class line_reader template auto async_read_line(std::string prompt, CompletionToken&& token) -> decltype( - asio::async_initiate( + asio::async_initiate( initiate_read_line(), token, this, prompt)) { - return asio::async_initiate( + return asio::async_initiate( initiate_read_line(), token, this, prompt); } }; diff --git a/asio/src/examples/cpp11/type_erasure/stdin_line_reader.cpp b/asio/src/examples/cpp11/type_erasure/stdin_line_reader.cpp index 43418f7e45..430553d47b 100644 --- a/asio/src/examples/cpp11/type_erasure/stdin_line_reader.cpp +++ b/asio/src/examples/cpp11/type_erasure/stdin_line_reader.cpp @@ -19,14 +19,14 @@ stdin_line_reader::stdin_line_reader(asio::any_io_executor ex) } void stdin_line_reader::async_read_line_impl(std::string prompt, - asio::any_completion_handler handler) + asio::any_completion_handler handler) { std::cout << prompt; std::cout.flush(); asio::async_read_until(stdin_, asio::dynamic_buffer(buffer_), '\n', asio::deferred( - [this](asio::error_code ec, std::size_t n) + [this](std::error_code ec, std::size_t n) { if (!ec) { diff --git a/asio/src/examples/cpp11/type_erasure/stdin_line_reader.hpp b/asio/src/examples/cpp11/type_erasure/stdin_line_reader.hpp index 489e7d282c..5e680f3409 100644 --- a/asio/src/examples/cpp11/type_erasure/stdin_line_reader.hpp +++ b/asio/src/examples/cpp11/type_erasure/stdin_line_reader.hpp @@ -21,7 +21,7 @@ class stdin_line_reader : public line_reader private: void async_read_line_impl(std::string prompt, - asio::any_completion_handler handler) override; + asio::any_completion_handler handler) override; asio::posix::stream_descriptor stdin_; std::string buffer_; diff --git a/asio/src/examples/cpp03/allocation/.gitignore b/asio/src/examples/cpp11/windows/.gitignore similarity index 100% rename from asio/src/examples/cpp03/allocation/.gitignore rename to asio/src/examples/cpp11/windows/.gitignore diff --git a/asio/src/examples/cpp03/windows/transmit_file.cpp b/asio/src/examples/cpp11/windows/transmit_file.cpp similarity index 88% rename from asio/src/examples/cpp03/windows/transmit_file.cpp rename to asio/src/examples/cpp11/windows/transmit_file.cpp index 891ba81241..f0feb0a6d8 100644 --- a/asio/src/examples/cpp03/windows/transmit_file.cpp +++ b/asio/src/examples/cpp11/windows/transmit_file.cpp @@ -9,11 +9,10 @@ // #include +#include #include +#include #include -#include -#include -#include #include "asio.hpp" #if defined(ASIO_HAS_WINDOWS_OVERLAPPED_PTR) @@ -47,7 +46,7 @@ void transmit_file(tcp_socket& socket, // The operation completed immediately, so a completion notification needs // to be posted. When complete() is called, ownership of the OVERLAPPED- // derived object passes to the io_context. - asio::error_code ec(last_error, + std::error_code ec(last_error, asio::error::get_system_category()); overlapped.complete(ec, 0); } @@ -60,10 +59,10 @@ void transmit_file(tcp_socket& socket, } class connection - : public boost::enable_shared_from_this + : public std::enable_shared_from_this { public: - typedef boost::shared_ptr pointer; + typedef std::shared_ptr pointer; static pointer create(asio::io_context& io_context, const std::string& filename) @@ -78,13 +77,13 @@ class connection void start() { - asio::error_code ec; + std::error_code ec; file_.assign(::CreateFile(filename_.c_str(), GENERIC_READ, 0, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 0), ec); if (file_.is_open()) { transmit_file(socket_, file_, - boost::bind(&connection::handle_write, shared_from_this(), + std::bind(&connection::handle_write, shared_from_this(), asio::placeholders::error, asio::placeholders::bytes_transferred)); } @@ -98,10 +97,10 @@ class connection { } - void handle_write(const asio::error_code& /*error*/, + void handle_write(const std::error_code& /*error*/, size_t /*bytes_transferred*/) { - asio::error_code ignored_ec; + std::error_code ignored_ec; socket_.shutdown(tcp_socket::shutdown_both, ignored_ec); } @@ -128,12 +127,12 @@ class server connection::create(acceptor_.get_executor().context(), filename_); acceptor_.async_accept(new_connection->socket(), - boost::bind(&server::handle_accept, this, new_connection, + std::bind(&server::handle_accept, this, new_connection, asio::placeholders::error)); } void handle_accept(connection::pointer new_connection, - const asio::error_code& error) + const std::error_code& error) { if (!error) {