// // echo_server.cpp // ~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2022 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 #if defined(BOOST_ASIO_HAS_CO_AWAIT) namespace net = boost::asio; namespace this_coro = net::this_coro; using net::ip::tcp; using net::detached; using executor_type = net::io_context::executor_type; using socket_type = net::basic_stream_socket; using tcp_socket = net::use_awaitable_t::as_default_on_t; using acceptor_type = net::basic_socket_acceptor; using tcp_acceptor = net::use_awaitable_t::as_default_on_t; using awaitable_type = net::awaitable; constexpr net::use_awaitable_t use_awaitable; awaitable_type echo(tcp_socket socket) { try { char data[1024]; for (;;) { std::size_t n = co_await socket.async_read_some(net::buffer(data), use_awaitable); co_await async_write(socket, net::buffer(data, n), use_awaitable); } } catch (std::exception const&) { //std::printf("echo Exception: %s\n", e.what()); } } awaitable_type listener() { auto ex = co_await this_coro::executor; tcp_acceptor acceptor(ex, {tcp::v4(), 55555}); for (;;) { tcp_socket socket = co_await acceptor.async_accept(use_awaitable); co_spawn(ex, echo(std::move(socket)), detached); } } int main() { try { net::io_context io_context{BOOST_ASIO_CONCURRENCY_HINT_UNSAFE_IO}; co_spawn(io_context, listener(), detached); io_context.run(); } catch (std::exception const& e) { std::printf("Exception: %s\n", e.what()); } } #else // defined(BOOST_ASIO_HAS_CO_AWAIT) auto main() -> int { std::cout << "Requires coroutine support." << std::endl; return 1; } #endif // defined(BOOST_ASIO_HAS_CO_AWAIT)