From 3a585b615e35fdedd2e78bfd8aa1c9e795dea6ce Mon Sep 17 00:00:00 2001 From: Christopher Kohlhoff Date: Wed, 4 Aug 2021 20:32:12 +1000 Subject: [PATCH] Add missing C++14 examples. --- doc/Jamfile.v2 | 4 +- doc/examples.qbk | 63 +++++++++++++++++ example/cpp14/iostreams/Jamfile.v2 | 31 +++++++++ example/cpp14/iostreams/http_client.cpp | 91 +++++++++++++++++++++++++ 4 files changed, 188 insertions(+), 1 deletion(-) create mode 100644 example/cpp14/iostreams/Jamfile.v2 create mode 100644 example/cpp14/iostreams/http_client.cpp diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index 13ff7c2c..ec8e2ae5 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -34,7 +34,9 @@ local example-names = cpp03/allocation cpp03/buffers cpp03/chat cpp03/echo cpp11/chat cpp11/echo cpp11/executors cpp11/fork cpp11/futures cpp11/handler_tracking cpp11/http/server cpp11/invocation cpp11/local cpp11/multicast cpp11/nonblocking cpp11/operations cpp11/socks4 cpp11/ssl - cpp11/timeouts cpp11/timers cpp11/spawn cpp14/operations cpp17/coroutines_ts ; + cpp11/timeouts cpp11/timers cpp11/spawn cpp14/deferred cpp14/echo + cpp14/executors cpp14/iostreams cpp14/operations cpp14/parallel_group + cpp17/coroutines_ts ; for local l in $(example-names) { diff --git a/doc/examples.qbk b/doc/examples.qbk index 0774b3ca..67611a64 100644 --- a/doc/examples.qbk +++ b/doc/examples.qbk @@ -527,6 +527,55 @@ Examples showing how to use UNIX domain (local) sockets. [section:cpp14_examples C++14 Examples] +[heading Deferred] + +Examples showing how to use the [link boost_asio.reference.experimental__deferred +`experimental::deferred`] completion token. + +* [@boost_asio/example/cpp14/deferred/deferred_1.cpp] +* [@boost_asio/example/cpp14/deferred/deferred_2.cpp] +* [@boost_asio/example/cpp14/deferred/deferred_3.cpp] +* [@boost_asio/example/cpp14/deferred/deferred_4.cpp] +* [@boost_asio/example/cpp14/deferred/deferred_5.cpp] +* [@boost_asio/example/cpp14/deferred/deferred_6.cpp] +* [@boost_asio/example/cpp14/deferred/deferred_7.cpp] + + +[heading Echo] + +A collection of simple clients and servers, showing the use of both synchronous +and asynchronous operations. + +* [@boost_asio/example/cpp14/echo/async_tcp_echo_server.cpp] +* [@boost_asio/example/cpp14/echo/async_udp_echo_server.cpp] +* [@boost_asio/example/cpp14/echo/blocking_tcp_echo_client.cpp] +* [@boost_asio/example/cpp14/echo/blocking_tcp_echo_server.cpp] +* [@boost_asio/example/cpp14/echo/blocking_udp_echo_client.cpp] +* [@boost_asio/example/cpp14/echo/blocking_udp_echo_server.cpp] + + +[heading Executors] + +Examples showing how to use the executor-related facilities. + +* [@boost_asio/example/cpp14/executors/actor.cpp] +* [@boost_asio/example/cpp14/executors/async_1.cpp] +* [@boost_asio/example/cpp14/executors/async_2.cpp] +* [@boost_asio/example/cpp14/executors/bank_account_1.cpp] +* [@boost_asio/example/cpp14/executors/bank_account_2.cpp] +* [@boost_asio/example/cpp14/executors/fork_join.cpp] +* [@boost_asio/example/cpp14/executors/pipeline.cpp] +* [@boost_asio/example/cpp14/executors/priority_scheduler.cpp] + + +[heading Iostreams] + +Two examples showing how to use [link boost_asio.reference.ip__tcp.iostream +ip::tcp::iostream]. + +* [@boost_asio/example/cpp14/iostreams/http_client.cpp] + + [heading Operations] Examples showing how to implement composed asynchronous operations as reusable library functions. @@ -541,6 +590,20 @@ Examples showing how to implement composed asynchronous operations as reusable l * [@boost_asio/example/cpp14/operations/composed_8.cpp] +[heading Parallel Groups] + +Examples showing how to use the [link +boost_asio.reference.experimental__make_parallel_group +`experimental::make_parallel_group`] operation. + +* [@boost_asio/example/cpp14/parallel_group/parallel_sort.cpp] +* [@boost_asio/example/cpp14/parallel_group/wait_for_all.cpp] +* [@boost_asio/example/cpp14/parallel_group/wait_for_one.cpp] +* [@boost_asio/example/cpp14/parallel_group/wait_for_one_error.cpp] +* [@boost_asio/example/cpp14/parallel_group/wait_for_one_success.cpp] + + + [endsect] diff --git a/example/cpp14/iostreams/Jamfile.v2 b/example/cpp14/iostreams/Jamfile.v2 new file mode 100644 index 00000000..e27b5644 --- /dev/null +++ b/example/cpp14/iostreams/Jamfile.v2 @@ -0,0 +1,31 @@ +# +# Copyright (c) 2003-2021 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) +# + +lib socket ; # SOLARIS +lib nsl ; # SOLARIS +lib ws2_32 ; # NT +lib mswsock ; # NT +lib ipv6 ; # HPUX +lib network ; # HAIKU + +project + : requirements + /boost/system//boost_system + BOOST_ALL_NO_LIB=1 + multi + solaris:socket + solaris:nsl + windows:_WIN32_WINNT=0x0501 + windows,gcc:ws2_32 + windows,gcc:mswsock + windows,gcc-cygwin:__USE_W32_SOCKETS + hpux,gcc:_XOPEN_SOURCE_EXTENDED + hpux:ipv6 + haiku:network + ; + +exe http_client : http_client.cpp ; diff --git a/example/cpp14/iostreams/http_client.cpp b/example/cpp14/iostreams/http_client.cpp new file mode 100644 index 00000000..24de21e3 --- /dev/null +++ b/example/cpp14/iostreams/http_client.cpp @@ -0,0 +1,91 @@ +// +// http_client.cpp +// ~~~~~~~~~~~~~~~ +// +// Copyright (c) 2003-2021 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 boost::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; + } + + boost::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(std::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; +}