TCP Echo Server — coroutines
// TCP echo server implemented with Boost.ASIO and C++20 coroutines
//
// Copyright (c) 2021 Andrzej Krzemieński (akrzemi1 at gmail dot com)
//
// Based heavily on the example by Christopher M. Kohlhoff at:
// https://www.boost.org/doc/libs/1_78_0/doc/html/boost_asio/example/cpp17/coroutines_ts/echo_server.cpp
//
// 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 <boost/asio/co_spawn.hpp>
#include <boost/asio/detached.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/signal_set.hpp>
#include <boost/asio/write.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <cstdio>
#include <iostream>
namespace asio = boost::asio;
namespace sys = boost::system;
using boost::asio::ip::tcp;
void report_error(std::string_view component, sys::error_code ec)
{
std::cerr << component << " failure: "
<< ec << " ()" << ec.message() << ")\n";
}
asio::awaitable<void> session(tcp::socket socket)
{
try
{
char data[1024];
for (;;)
{
std::size_t n = co_await socket.async_read_some(asio::buffer(data), asio::use_awaitable);
co_await async_write(socket, asio::buffer(data, n), asio::use_awaitable);
}
}
catch (sys::system_error const& e)
{
if (e.code() == asio::error::eof)
std::cerr << "Session done \n";
else
report_error("Session", e.code());
}
}
asio::awaitable<void> listener(asio::io_context& context, unsigned short port)
{
tcp::acceptor acceptor(context, {tcp::v4(), port});
try
{
for (;;)
{
tcp::socket socket = co_await acceptor.async_accept(asio::use_awaitable);
asio::co_spawn(context, session(std::move(socket)), asio::detached);
}
}
catch (sys::system_error const& e)
{
report_error("Listener", e.code());
}
}
int main()
{
try
{
asio::io_context context;
asio::signal_set signals(context, SIGINT, SIGTERM);
signals.async_wait([&](auto, auto){ context.stop(); });
auto listen = listener(context, 55555);
asio::co_spawn(context, std::move(listen), asio::detached);
context.run();
std::cerr << "Server done \n";
}
catch (std::exception& e)
{
std::cerr << "Server failure: " << e.what() << "\n";
}
}
Like this:
Like Loading...