Quick Start
This page gets you from zero to a working TCP echo client in five minutes.
| Corosio requires C++20 with coroutine support. |
Echo Client Example
Create a file echo_client.cpp:
#include <boost/corosio.hpp>
#include <boost/capy/task.hpp>
#include <boost/capy/ex/async_run.hpp>
#include <iostream>
namespace corosio = boost::corosio;
namespace capy = boost::capy;
// Handle a single client connection
capy::task<void> handle_client(corosio::socket client)
{
char buf[1024];
for (;;)
{
// Read data from client
auto [read_ec, n] = co_await client.read_some(
boost::buffers::mutable_buffer(buf, sizeof(buf)));
if (read_ec)
{
if (read_ec != capy::error::eof)
std::cerr << "Read error: " << read_ec.message() << "\n";
co_return;
}
// Echo it back
auto [write_ec, written] = co_await client.write_some(
boost::buffers::const_buffer(buf, n));
if (write_ec)
{
std::cerr << "Write error: " << write_ec.message() << "\n";
co_return;
}
}
}
// Client connection handler
capy::task<void> client_loop(corosio::io_context& ioc)
{
corosio::socket client(ioc);
client.open();
// Connect to server
auto ec = co_await client.connect(
corosio::endpoint(boost::urls::ipv4_address::loopback(), 8080));
if (ec)
{
std::cerr << "Connect error: " << ec.message() << "\n";
co_return;
}
// Launch client handler
co_await handle_client(std::move(client));
}
int main()
{
corosio::io_context ioc;
capy::async_run(ioc.get_executor())(client_loop(ioc));
ioc.run();
}
Build and Run
-
CMake
-
MSVC
-
GCC
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake --build .
./echo_server
cl /std:c++20 /EHsc /O2 echo_server.cpp /I path/to/boost /link /LIBPATH:path/to/boost/stage/lib
.\echo_client.exe
g++ -std=c++20 -fcoroutines -O2 echo_client.cpp -o echo_client \
-I/path/to/boost -L/path/to/boost/stage/lib \
-lboost_system -pthread
./echo_client
Test the Client
Run the client and it will connect to a server on localhost:8080. Make sure you have a server running on that port, or the connection will fail.
What Just Happened?
-
client_loopcreates a socket and connects to the server -
handle_clientreads data withco_await client.read_some(…) -
The data is echoed back with
co_await client.write_some(…) -
The loop continues until the client disconnects
The key insight: all coroutines run on the same executor because affinity propagates automatically. The I/O context handles multiplexing I/O operations on a single thread.
Next Steps
-
I/O Context — Learn about the event loop
-
Sockets — Detailed socket operations
-
Affine Awaitables — How affinity propagation works