### Synchronous TCP Server Example Source: https://context7.com/boostorg/asio/llms.txt A basic synchronous TCP server that accepts connections and spawns a new thread for each client. It echoes received data back to the client. ```cpp #include #include #include using boost::asio::ip::tcp; void session(tcp::socket sock) { try { char data[1024]; for (;;) { boost::system::error_code error; size_t length = sock.read_some(boost::asio::buffer(data), error); if (error == boost::asio::error::eof) break; // Connection closed cleanly else if (error) throw boost::system::system_error(error); // Echo data back boost::asio::write(sock, boost::asio::buffer(data, length)); } } catch (std::exception& e) { std::cerr << "Session error: " << e.what() << std::endl; } } int main() { try { boost::asio::io_context io_context; tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v4(), 12345)); std::cout << "Server listening on port 12345..." << std::endl; for (;;) { // Accept connection and spawn thread to handle it std::thread(session, acceptor.accept()).detach(); } } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << std::endl; } return 0; } ``` -------------------------------- ### Synchronous TCP Client Connection and Data Transfer Source: https://context7.com/boostorg/asio/llms.txt A synchronous TCP client example that resolves a hostname, connects to a server, sends a message, and receives a reply. It uses `boost::asio::connect` for connection and `boost::asio::write`/`socket.read_some` for data transfer. ```cpp #include #include #include using boost::asio::ip::tcp; int main() { try { boost::asio::io_context io_context; // Resolve hostname to endpoint(s) tcp::resolver resolver(io_context); auto endpoints = resolver.resolve("localhost", "12345"); // Create and connect socket tcp::socket socket(io_context); boost::asio::connect(socket, endpoints); // Send data const char* message = "Hello, Server!"; boost::asio::write(socket, boost::asio::buffer(message, std::strlen(message))); // Receive response char reply[1024]; size_t reply_length = socket.read_some(boost::asio::buffer(reply)); std::cout << "Reply: "; std::cout.write(reply, reply_length); std::cout << std::endl; } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << std::endl; } return 0; } ``` -------------------------------- ### Asynchronous TCP Echo Server Example Source: https://context7.com/boostorg/asio/llms.txt An asynchronous TCP server that efficiently handles multiple connections without a thread-per-connection overhead. It uses completion handlers and the `shared_from_this` pattern for session management. ```cpp #include #include #include using boost::asio::ip::tcp; class session : public std::enable_shared_from_this { public: session(tcp::socket socket) : socket_(std::move(socket)) {} void start() { do_read(); } private: void do_read() { auto self(shared_from_this()); socket_.async_read_some(boost::asio::buffer(data_, max_length), [this, self](boost::system::error_code ec, std::size_t length) { if (!ec) { do_write(length); } }); } void do_write(std::size_t length) { auto self(shared_from_this()); boost::asio::async_write(socket_, boost::asio::buffer(data_, length), [this, self](boost::system::error_code ec, std::size_t) // Removed unused parameter { if (!ec) { do_read(); } }); } tcp::socket socket_; enum { max_length = 1024 }; char data_[max_length]; }; class server { public: server(boost::asio::io_context& io_context, short port) : acceptor_(io_context, tcp::endpoint(tcp::v4(), port)) { do_accept(); } private: void do_accept() { acceptor_.async_accept( [this](boost::system::error_code ec, tcp::socket socket) { if (!ec) { std::make_shared(std::move(socket))->start(); } do_accept(); // Accept next connection }); } tcp::acceptor acceptor_; }; int main() { try { boost::asio::io_context io_context; server s(io_context, 12345); io_context.run(); } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << std::endl; } return 0; } ``` -------------------------------- ### Synchronous and Asynchronous steady_timer waits Source: https://context7.com/boostorg/asio/llms.txt Illustrates both synchronous `wait()` and asynchronous `async_wait()` operations using `steady_timer`. Includes examples of a timer with a lambda handler and modifying expiry time, as well as handling cancellation. ```cpp #include #include void print(const boost::system::error_code& ec) { if (!ec) { std::cout << "Hello, world!" << std::endl; } } int main() { boost::asio::io_context io; // Synchronous timer wait boost::asio::steady_timer sync_timer(io, boost::asio::chrono::seconds(1)); sync_timer.wait(); // Blocks for 1 second std::cout << "Synchronous wait complete" << std::endl; // Asynchronous timer wait boost::asio::steady_timer async_timer(io, boost::asio::chrono::seconds(2)); async_timer.async_wait(&print); // Timer with lambda and expiry modification boost::asio::steady_timer timer3(io); timer3.expires_after(std::chrono::milliseconds(500)); timer3.async_wait([](const boost::system::error_code& ec) { if (ec == boost::asio::error::operation_aborted) { std::cout << "Timer was cancelled" << std::endl; } else if (!ec) { std::cout << "500ms timer expired" << std::endl; } }); io.run(); return 0; } ``` -------------------------------- ### UDP Echo Server and Client Example Source: https://context7.com/boostorg/asio/llms.txt Demonstrates UDP socket communication. The server echoes received datagrams back to the sender, and the client sends a message and prints the reply. ```cpp #include #include #include using boost::asio::ip::udp; // UDP Echo Server void run_server(unsigned short port) { boost::asio::io_context io_context; udp::socket socket(io_context, udp::endpoint(udp::v4(), port)); char data[1024]; udp::endpoint sender_endpoint; for (;;) // Changed from while(true) to for(;;) { size_t length = socket.receive_from( boost::asio::buffer(data, 1024), sender_endpoint); // Echo back to sender socket.send_to(boost::asio::buffer(data, length), sender_endpoint); } } // UDP Client void run_client(const char* host, const char* port) { boost::asio::io_context io_context; udp::socket socket(io_context, udp::endpoint(udp::v4(), 0)); udp::resolver resolver(io_context); auto endpoints = resolver.resolve(udp::v4(), host, port); const char* message = "Hello UDP Server!"; socket.send_to(boost::asio::buffer(message, std::strlen(message)), *endpoints.begin()); char reply[1024]; udp::endpoint sender_endpoint; size_t reply_length = socket.receive_from( boost::asio::buffer(reply, 1024), sender_endpoint); std::cout << "Reply: "; std::cout.write(reply, reply_length); std::cout << std::endl; } int main(int argc, char* argv[]) { if (argc == 2) { run_server(std::atoi(argv[1])); // Server mode } else if (argc == 3) { run_client(argv[1], argv[2]); // Client mode } return 0; } ``` -------------------------------- ### Asynchronous TCP Daytime Server - tcp_server Class Source: https://github.com/boostorg/asio/blob/develop/example/cpp11/tutorial/daytime_dox.txt Defines the tcp_server class for an asynchronous TCP daytime server. It initializes an acceptor and starts accepting connections asynchronously. ```cpp #include #include class tcp_server { public: tcp_server(boost::asio::io_context& io_context) : acceptor_(io_context, tcp::endpoint(tcp::v4(), 13)) { start_accept(); } private: void start_accept() { tcp_session* new_session = new tcp_session(acceptor_.get_executor().context()); acceptor_.async_accept(new_session->socket(), boost::bind(&tcp_server::handle_accept, this, new_session, boost::asio::placeholders::error)); } void handle_accept(tcp_session* new_session, const boost::system::error_code& error) { if (!error) { new_session->start(); } else delete new_session; start_accept(); } tcp::acceptor acceptor_; }; ``` -------------------------------- ### Run io_context with a steady_timer Source: https://context7.com/boostorg/asio/llms.txt Demonstrates creating an `io_context`, setting up a `steady_timer` for a 2-second delay, and running the event loop to process the timer's completion handler. ```cpp #include #include int main() { // Create the I/O context - the central hub for all I/O operations boost::asio::io_context io_context; // Create a timer that will expire in 2 seconds boost::asio::steady_timer timer(io_context, std::chrono::seconds(2)); // Set up an asynchronous wait with a completion handler timer.async_wait([](const boost::system::error_code& ec) { if (!ec) { std::cout << "Timer expired!" << std::endl; } }); // Run the event loop - this blocks until all work is complete // Handlers are only invoked from within run() io_context.run(); // Output: Timer expired! (after 2 seconds) return 0; } ``` -------------------------------- ### Include Headers for Timer Synchronisation Source: https://github.com/boostorg/asio/blob/develop/example/cpp11/tutorial/timer_dox.txt Required headers for using Boost.Asio timers and strands. ```cpp #include #include #include #include ``` -------------------------------- ### Asynchronous TCP Daytime Server - Main Function Source: https://github.com/boostorg/asio/blob/develop/example/cpp11/tutorial/daytime_dox.txt Sets up the main function for an asynchronous TCP daytime server. It creates an io_context and a tcp_server object, then runs the io_context to process asynchronous operations. ```cpp #include #include #include "tcp_server.hpp" int main() { try { boost::asio::io_context io_context; tcp_server server(io_context); io_context.run(); } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; } return 0; } ``` -------------------------------- ### Implement an Asynchronous HTTP Client in C++ Source: https://context7.com/boostorg/asio/llms.txt Uses boost::asio::io_context to manage asynchronous operations including DNS resolution, socket connection, and stream reading. Requires linking against Boost.Asio and appropriate system libraries. ```cpp #include #include #include #include #include using boost::asio::ip::tcp; class http_client { public: http_client(boost::asio::io_context& io_context, const std::string& server, const std::string& path) : resolver_(io_context), socket_(io_context) { // Build HTTP request std::ostream request_stream(&request_); request_stream << "GET " << path << " HTTP/1.0\r\n"; request_stream << "Host: " << server << "\r\n"; request_stream << "Accept: */*\r\n"; request_stream << "Connection: close\r\n\r\n"; resolver_.async_resolve(server, "http", [this](const boost::system::error_code& err, const tcp::resolver::results_type& endpoints) { if (!err) { boost::asio::async_connect(socket_, endpoints, [this](auto err, auto) { if (!err) do_write(); }); } }); } private: void do_write() { boost::asio::async_write(socket_, request_, [this](auto err, auto) { if (!err) do_read_status(); }); } void do_read_status() { boost::asio::async_read_until(socket_, response_, "\r\n", [this](auto err, auto) { if (!err) { std::istream response_stream(&response_); std::string http_version; unsigned int status_code; response_stream >> http_version >> status_code; std::cout << "Status: " << status_code << "\n"; do_read_headers(); } }); } void do_read_headers() { boost::asio::async_read_until(socket_, response_, "\r\n\r\n", [this](auto err, auto) { if (!err) { std::istream response_stream(&response_); std::string header; while (std::getline(response_stream, header) && header != "\r") std::cout << header << "\n"; std::cout << "\n"; do_read_content(); } }); } void do_read_content() { boost::asio::async_read(socket_, response_, boost::asio::transfer_at_least(1), [this](auto err, auto) { if (!err) { std::cout << &response_; do_read_content(); } }); } tcp::resolver resolver_; tcp::socket socket_; boost::asio::streambuf request_; boost::asio::streambuf response_; }; int main() { boost::asio::io_context io_context; http_client client(io_context, "www.boost.org", "/LICENSE_1_0.txt"); io_context.run(); return 0; } ``` -------------------------------- ### Implement SSL/TLS Client with Boost.Asio Source: https://context7.com/boostorg/asio/llms.txt Uses ssl::stream to wrap a TCP socket for encrypted communication. Requires OpenSSL integration and a configured ssl::context. ```cpp #include #include #include #include using boost::asio::ip::tcp; class ssl_client { public: ssl_client(boost::asio::io_context& io_context, boost::asio::ssl::context& ssl_context, const tcp::resolver::results_type& endpoints) : socket_(io_context, ssl_context) { socket_.set_verify_mode(boost::asio::ssl::verify_peer); socket_.set_verify_callback( [this](bool preverified, boost::asio::ssl::verify_context& ctx) { 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; }); // Connect underlying TCP socket boost::asio::async_connect(socket_.lowest_layer(), endpoints, [this](const boost::system::error_code& error, const tcp::endpoint&) { if (!error) { do_handshake(); } else { std::cout << "Connect failed: " << error.message() << "\n"; } }); } private: void do_handshake() { socket_.async_handshake(boost::asio::ssl::stream_base::client, [this](const boost::system::error_code& error) { if (!error) { std::cout << "SSL handshake successful!\n"; // Now can do async_read/async_write on socket_ } else { std::cout << "Handshake failed: " << error.message() << "\n"; } }); } boost::asio::ssl::stream socket_; }; int main() { try { boost::asio::io_context io_context; tcp::resolver resolver(io_context); auto endpoints = resolver.resolve("www.google.com", "443"); // Configure SSL context boost::asio::ssl::context ctx(boost::asio::ssl::context::tlsv12_client); ctx.set_default_verify_paths(); ssl_client client(io_context, ctx, endpoints); io_context.run(); } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; } return 0; } ``` -------------------------------- ### Main Function for Combined Server Source: https://github.com/boostorg/asio/blob/develop/example/cpp11/tutorial/daytime_dox.txt Initializes and runs a combined TCP and UDP asynchronous server. Creates separate server objects for TCP and UDP to handle different types of client requests concurrently. ```cpp int main() { try { boost::asio::io_context io_context; tcp_server tcp_server_obj(io_context); udp_server udp_server_obj(io_context); io_context.run(); } catch (std::exception& e) { std::cerr << e.what() << std::endl; } return 0; } ``` -------------------------------- ### Implement synchronous UDP daytime client Source: https://github.com/boostorg/asio/blob/develop/example/cpp11/tutorial/daytime_dox.txt Demonstrates resolving endpoints and receiving datagrams using UDP sockets. ```cpp #include #include #include using boost::asio::ip::udp; ``` ```cpp boost::asio::io_context io_context; udp::resolver resolver(io_context); udp::endpoint receiver_endpoint(*resolver.resolve(udp::v4(), argv[1], "daytime")); udp::socket socket(io_context); socket.open(udp::v4()); boost::array send_buf = {{ 0 }}; socket.send_to(boost::asio::buffer(send_buf), receiver_endpoint); boost::array recv_buf; udp::endpoint sender_endpoint; size_t len = socket.receive_from(boost::asio::buffer(recv_buf), sender_endpoint); std::cout.write(recv_buf.data(), len); ``` ```cpp } catch (std::exception& e) { std::cerr << e.what() << std::endl; } ``` -------------------------------- ### Create Buffers from C Arrays, std::array, std::vector, and std::string Source: https://context7.com/boostorg/asio/llms.txt Demonstrates creating fixed-size buffers from various C++ memory structures. The `buffer()` function creates views into existing memory. ```cpp #include #include #include #include void buffer_examples() { // Fixed-size buffer from C array char data[1024]; auto buf1 = boost::asio::buffer(data); auto buf2 = boost::asio::buffer(data, 512); // First 512 bytes only // Buffer from std::array std::array arr; auto buf3 = boost::asio::buffer(arr); // Buffer from std::vector std::vector vec(1024); auto buf4 = boost::asio::buffer(vec); // Buffer from std::string (const) std::string str = "Hello, World!"; auto buf5 = boost::asio::buffer(str); // Dynamic buffer that grows as needed (for read_until, etc.) std::string dynamic_str; auto dyn_buf = boost::asio::dynamic_buffer(dynamic_str); std::vector dynamic_vec; auto dyn_buf2 = boost::asio::dynamic_buffer(dynamic_vec, 65536); // Max size // Scatter-gather I/O with multiple buffers std::array buffers = { boost::asio::buffer(data, 512), boost::asio::buffer(vec) }; // Buffer arithmetic auto buf_offset = buf1 + 100; // Skip first 100 bytes std::size_t size = boost::asio::buffer_size(buf1); void* ptr = buf1.data(); } ``` -------------------------------- ### Implement synchronous UDP daytime server Source: https://github.com/boostorg/asio/blob/develop/example/cpp11/tutorial/daytime_dox.txt Sets up a UDP socket to listen on port 13 and respond to incoming datagrams. ```cpp int main() { try { boost::asio::io_context io_context; udp::socket socket(io_context, udp::endpoint(udp::v4(), 13)); for (;;) { boost::array recv_buf; udp::endpoint remote_endpoint; socket.receive_from(boost::asio::buffer(recv_buf), remote_endpoint); std::string message = make_daytime_string(); boost::system::error_code ignored_error; socket.send_to(boost::asio::buffer(message), remote_endpoint, 0, ignored_error); } } catch (std::exception& e) { std::cerr << e.what() << std::endl; } } ``` -------------------------------- ### Implement UNIX Domain Sockets Server Source: https://context7.com/boostorg/asio/llms.txt Provides inter-process communication using the filesystem namespace. Only available on POSIX systems where BOOST_ASIO_HAS_LOCAL_SOCKETS is defined. ```cpp #include #include #include #include #if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS) using boost::asio::local::stream_protocol; class unix_session : public std::enable_shared_from_this { public: unix_session(stream_protocol::socket sock) : socket_(std::move(sock)) {} void start() { do_read(); } private: void do_read() { auto self(shared_from_this()); socket_.async_read_some(boost::asio::buffer(data_), [this, self](boost::system::error_code ec, std::size_t length) { if (!ec) do_write(length); }); } void do_write(std::size_t length) { auto self(shared_from_this()); boost::asio::async_write(socket_, boost::asio::buffer(data_, length), [this, self](boost::system::error_code ec, std::size_t) { if (!ec) do_read(); }); } stream_protocol::socket socket_; std::array data_; }; class unix_server { public: unix_server(boost::asio::io_context& io_context, const std::string& path) : acceptor_(io_context, stream_protocol::endpoint(path)) { do_accept(); } private: void do_accept() { acceptor_.async_accept( [this](boost::system::error_code ec, stream_protocol::socket socket) { if (!ec) { std::make_shared(std::move(socket))->start(); } do_accept(); }); } acceptor_; }; // Server: ./program /tmp/mysocket.sock // Client uses: stream_protocol::socket s(io); s.connect(stream_protocol::endpoint("/tmp/mysocket.sock")); #endif ``` -------------------------------- ### UDP Server Class Definition (Daytime.7) Source: https://github.com/boostorg/asio/blob/develop/example/cpp11/tutorial/daytime_dox.txt Re-declares the udp_server class, which is reused from a previous tutorial step (Daytime.6) for the combined server application. It handles listening on UDP port 13. ```cpp class udp_server { public: udp_server(boost::asio::io_context& io_context) : socket_(io_context, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 13)) { start_receive(); } private: void start_receive() { socket_.async_receive_from( boost::asio::buffer(recv_buffer_), remote_endpoint_, boost::bind(&udp_server::handle_receive, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } void handle_receive(const boost::system::error_code& error, size_t bytes_transferred) { if (error == boost::asio::error::message_size) return; std::make_ready_time_string(make_daytime_string()); socket_.async_send_to( boost::asio::buffer(message_), remote_endpoint_, boost::bind(&udp_server::handle_send, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); start_receive(); } void handle_send(const boost::system::error_code& /*error*/, size_t /*bytes_transferred*/) { } boost::asio::ip::udp::socket socket_; boost::asio::ip::udp::endpoint remote_endpoint_; std::array recv_buffer_; std::string message_; }; ``` -------------------------------- ### Implement Stackful Coroutines with spawn and yield_context Source: https://context7.com/boostorg/asio/llms.txt Uses spawn to create coroutines that allow asynchronous operations to be written in a synchronous style. Requires Boost.Context and is compatible with C++11. ```cpp #include #include #include #include #include #include #include #include using boost::asio::ip::tcp; class session : public std::enable_shared_from_this { public: session(boost::asio::io_context& io_context, tcp::socket socket) : socket_(std::move(socket)), timer_(io_context), strand_(io_context.get_executor()) {} void go() { auto self(shared_from_this()); // Main I/O coroutine boost::asio::spawn(strand_, [this, self](boost::asio::yield_context yield) { try { char data[128]; for (;;) { timer_.expires_after(std::chrono::seconds(10)); // yield_context enables async operations to look synchronous std::size_t n = socket_.async_read_some( boost::asio::buffer(data), yield); boost::asio::async_write(socket_, boost::asio::buffer(data, n), yield); } } catch (std::exception&) { socket_.close(); timer_.cancel(); } }, boost::asio::detached); // Timeout watchdog coroutine boost::asio::spawn(strand_, [this, self](boost::asio::yield_context yield) { while (socket_.is_open()) { boost::system::error_code ec; timer_.async_wait(yield[ec]); if (timer_.expiry() <= boost::asio::steady_timer::clock_type::now()) socket_.close(); } }, boost::asio::detached); } private: tcp::socket socket_; boost::asio::steady_timer timer_; boost::asio::strand strand_; }; ``` -------------------------------- ### Run io_context in Multiple Threads Source: https://github.com/boostorg/asio/blob/develop/example/cpp11/tutorial/timer_dox.txt The main function executes the io_context from both the main thread and a secondary thread to demonstrate concurrent execution. ```cpp int main() { boost::asio::io_context io; printer p(io); boost::thread t(boost::bind(&boost::asio::io_context::run, &io)); io.run(); t.join(); return 0; } ``` -------------------------------- ### Perform an asynchronous timer wait Source: https://github.com/boostorg/asio/blob/develop/example/cpp11/tutorial/timer_dox.txt Demonstrates an asynchronous wait using async_wait. Requires calling io_context::run to process the completion handler. ```cpp #include #include void print(const boost::system::error_code& /*e*/) { std::cout << "Hello, world!" << std::endl; } int main() { boost::asio::io_context io; boost::asio::steady_timer t(io, boost::asio::chrono::seconds(5)); t.async_wait(&print); io.run(); return 0; } ``` -------------------------------- ### Synchronous TCP Daytime Client Source: https://github.com/boostorg/asio/blob/develop/example/cpp11/tutorial/daytime_dox.txt Implements a client that connects to a daytime service to retrieve the current time. Requires specifying the server address as a command-line argument. ```cpp #include #include #include using boost::asio::ip::tcp; int main(int argc, char* argv[]) { try { if (argc != 2) { std::cerr << "Usage: daytime1 \n"; return 1; } boost::asio::io_context io_context; tcp::resolver resolver(io_context); tcp::resolver::results_type endpoints = resolver.resolve(argv[1], "daytime"); tcp::socket socket(io_context); boost::asio::connect(socket, endpoints); for (;;) { std::array buf; boost::system::error_code error; size_t len = socket.read_some(boost::asio::buffer(buf), error); if (error == boost::asio::error::eof) break; // Connection closed cleanly by peer. else if (error) throw boost::system::system_error(error); // Some other error. std::cout.write(buf.data(), len); } } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; } return 0; } ``` -------------------------------- ### TCP Server Class Definition (Daytime.7) Source: https://github.com/boostorg/asio/blob/develop/example/cpp11/tutorial/daytime_dox.txt Re-declares the tcp_connection and tcp_server classes, which are reused from a previous tutorial step (Daytime.3) for the combined server application. ```cpp class tcp_connection { public: typedef boost::shared_ptr pointer; static pointer create(boost::asio::io_context& io_context) { return pointer(new tcp_connection(io_context)); } tcp_protocol::socket& socket() { return socket_; } void start() { boost::asio::write(socket_, boost::asio::buffer(message_)); } private: tcp_connection(boost::asio::io_context& io_context) : socket_(io_context) { } std::string message_ = make_daytime_string(); tcp_protocol::socket socket_; }; class tcp_server { public: tcp_server(boost::asio::io_context& io_context) : io_context_(io_context), acceptor_( io_context_, boost::asio::ip::tcp::v4(), boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 13)) { start_accept(); } private: void start_accept() { tcp_connection::pointer new_connection = tcp_connection::create(io_context_); acceptor_.async_accept(new_connection->socket(), boost::bind(&tcp_server::handle_accept, this, new_connection, boost::asio::placeholders::error)); } void handle_accept(tcp_connection::pointer new_connection, const boost::system::error_code& error) { if (!error) { new_connection->start(); } start_accept(); } boost::asio::io_context& io_context_; boost::asio::ip::tcp::acceptor acceptor_; }; ``` -------------------------------- ### Serialized Handler Execution with Strands Source: https://context7.com/boostorg/asio/llms.txt Illustrates using `boost::asio::strand` to ensure that handlers posted to it execute serially, preventing race conditions even when the `io_context` is run by multiple threads. No explicit locking is needed. ```cpp #include #include #include int main() { boost::asio::io_context io_context; boost::asio::strand strand( io_context.get_executor()); int counter = 0; // These handlers are guaranteed to execute serially, not concurrently for (int i = 0; i < 10; ++i) { boost::asio::post(strand, [&counter, i]() { ++counter; // Safe without mutex - strand serializes access std::cout << "Handler " << i << ", counter = " << counter << "\n"; }); } // Run io_context from multiple threads std::thread t1([&]() { io_context.run(); }); std::thread t2([&]() { io_context.run(); }); t1.join(); t2.join(); std::cout << "Final counter: " << counter << "\n"; return 0; } ``` -------------------------------- ### C++20 Coroutine Echo Server Source: https://context7.com/boostorg/asio/llms.txt An echo server implementation using C++20 coroutines with Boost.Asio. It supports concurrent client connections and handles read/write operations asynchronously using `co_await`. Requires C++20 compiler support. ```cpp #include #include #include #include #include #include #include using boost::asio::ip::tcp; using boost::asio::awaitable; using boost::asio::co_spawn; using boost::asio::detached; using boost::asio::use_awaitable; namespace this_coro = boost::asio::this_coro; awaitable echo(tcp::socket socket) { try { char data[1024]; for (;;) { // co_await suspends coroutine until operation completes std::size_t n = co_await socket.async_read_some( boost::asio::buffer(data), use_awaitable); co_await async_write(socket, boost::asio::buffer(data, n), use_awaitable); } } catch (std::exception& e) { std::printf("echo Exception: %s\n", e.what()); } } awaitable listener() { auto executor = co_await this_coro::executor; tcp::acceptor acceptor(executor, {tcp::v4(), 55555}); for (;;) { tcp::socket socket = co_await acceptor.async_accept(use_awaitable); co_spawn(executor, echo(std::move(socket)), detached); } } int main() { try { boost::asio::io_context io_context(1); // Handle Ctrl+C gracefully boost::asio::signal_set signals(io_context, SIGINT, SIGTERM); signals.async_wait([&](auto, auto) { io_context.stop(); }); co_spawn(io_context, listener(), detached); io_context.run(); } catch (std::exception& e) { std::printf("Exception: %s\n", e.what()); } } ``` -------------------------------- ### Perform a synchronous timer wait Source: https://github.com/boostorg/asio/blob/develop/example/cpp11/tutorial/timer_dox.txt Demonstrates a blocking wait using boost::asio::steady_timer. The wait call blocks until the timer expires. ```cpp #include #include int main() { boost::asio::io_context io; boost::asio::steady_timer t(io, boost::asio::chrono::seconds(5)); t.wait(); std::cout << "Hello, world!" << std::endl; return 0; } ``` -------------------------------- ### Asynchronous File Copy Source: https://context7.com/boostorg/asio/llms.txt Performs an asynchronous file copy operation. Requires platforms with native async file I/O support. Ensure correct command-line arguments are provided. ```cpp #include #include #if defined(BOOST_ASIO_HAS_FILE) class file_copier { public: file_copier(boost::asio::io_context& io_context, const char* from, const char* to) : from_file_(io_context, from, boost::asio::stream_file::read_only), to_file_(io_context, to, boost::asio::stream_file::write_only | boost::asio::stream_file::create | boost::asio::stream_file::truncate) {} void start() { do_read(); } private: void do_read() { from_file_.async_read_some(boost::asio::buffer(data_), [this](boost::system::error_code error, std::size_t n) { if (!error) { do_write(n); } else if (error != boost::asio::error::eof) { std::cerr << "Read error: " << error.message() << "\n"; } }); } void do_write(std::size_t n) { boost::asio::async_write(to_file_, boost::asio::buffer(data_, n), [this](boost::system::error_code error, std::size_t) { if (!error) { do_read(); } else { std::cerr << "Write error: " << error.message() << "\n"; } }); } boost::asio::stream_file from_file_; boost::asio::stream_file to_file_; char data_[4096]; }; int main(int argc, char* argv[]) { if (argc != 3) { std::cerr << "Usage: file_copy \n"; return 1; } boost::asio::io_context io_context; file_copier copier(io_context, argv[1], argv[2]); copier.start(); io_context.run(); return 0; } #endif ``` -------------------------------- ### Parallel Operations with wait_for_one Source: https://context7.com/boostorg/asio/llms.txt Demonstrates using `experimental::parallel_group` to run multiple asynchronous operations concurrently and wait for the first one to complete. Other operations will be canceled. ```cpp #include #include #include int main() { boost::asio::io_context ctx; boost::asio::steady_timer timer1(ctx, std::chrono::seconds(2)); boost::asio::steady_timer timer2(ctx, std::chrono::seconds(5)); // Wait for the first operation to complete, cancel the others boost::asio::experimental::make_parallel_group( timer1.async_wait(boost::asio::deferred), timer2.async_wait(boost::asio::deferred) ).async_wait( boost::asio::experimental::wait_for_one(), [](std::array completion_order, boost::system::error_code ec1, boost::system::error_code ec2) { std::cout << "First to complete: " << completion_order[0] << "\n"; std::cout << "Timer 1: " << ec1.message() << "\n"; std::cout << "Timer 2: " << ec2.message() << "\n"; // Timer 2 will show "operation canceled" }); ctx.run(); return 0; } ``` -------------------------------- ### Package Asynchronous Operations with deferred Source: https://context7.com/boostorg/asio/llms.txt Uses the deferred completion token to package an asynchronous operation for later execution, enabling lazy evaluation. ```cpp #include #include using boost::asio::deferred; int main() { boost::asio::io_context ctx; boost::asio::steady_timer timer(ctx); timer.expires_after(std::chrono::seconds(1)); // Package the operation without starting it auto deferred_op = timer.async_wait(deferred); // Later: start the operation with a completion handler std::move(deferred_op)( [](boost::system::error_code ec) { std::cout << "timer finished: " << ec.message() << "\n"; }); ctx.run(); return 0; } ``` -------------------------------- ### Synchronous TCP Daytime Server Source: https://github.com/boostorg/asio/blob/develop/example/cpp11/tutorial/daytime_dox.txt Implements an iterative server that listens for incoming TCP connections on port 13 and sends the current time to clients. ```cpp #include #include #include #include using boost::asio::ip::tcp; std::string make_daytime_string() { std::time_t now = std::time(0); return std::ctime(&now); } int main() { try { boost::asio::io_context io_context; tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v4(), 13)); for (;;) { tcp::socket socket(io_context); acceptor.accept(socket); std::string message = make_daytime_string(); boost::system::error_code ignored_error; boost::asio::write(socket, boost::asio::buffer(message), ignored_error); } } catch (std::exception& e) { std::cerr << e.what() << std::endl; } return 0; } ``` -------------------------------- ### UDP Server Class Definition Source: https://github.com/boostorg/asio/blob/develop/example/cpp11/tutorial/daytime_dox.txt Defines the structure of a UDP server, including its constructor and methods for handling asynchronous operations. Requires initialization of a socket to listen on UDP port 13. ```cpp class udp_server { public: udp_server(boost::asio::io_context& io_context) : socket_(io_context, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 13)) { start_receive(); } private: void start_receive() { socket_.async_receive_from( boost::asio::buffer(recv_buffer_), remote_endpoint_, boost::bind(&udp_server::handle_receive, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } void handle_receive(const boost::system::error_code& error, size_t bytes_transferred) { if (error == boost::asio::error::message_size) return; std::make_ready_time_string(make_daytime_string()); socket_.async_send_to( boost::asio::buffer(message_), remote_endpoint_, boost::bind(&udp_server::handle_send, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); start_receive(); } void handle_send(const boost::system::error_code& /*error*/, size_t /*bytes_transferred*/) { } udp_protocol::socket socket_; udp_protocol::endpoint remote_endpoint_; std::array recv_buffer_; std::string message_; }; ``` -------------------------------- ### Implement Printer Handlers Source: https://github.com/boostorg/asio/blob/develop/example/cpp11/tutorial/timer_dox.txt Handlers print to standard output and increment a shared counter, protected by the strand. ```cpp ~printer() { std::cout << "Final count is " << count_ << "\n"; } void print1() { if (count_ < 10) { std::cout << "Timer 1: " << count_ << "\n"; ++count_; timer1_.expires_at(timer1_.expiry() + boost::asio::chrono::seconds(1)); timer1_.async_wait(boost::asio::bind_executor(strand_, boost::bind(&printer::print1, this))); } } void print2() { if (count_ < 10) { std::cout << "Timer 2: " << count_ << "\n"; ++count_; timer2_.expires_at(timer2_.expiry() + boost::asio::chrono::seconds(1)); timer2_.async_wait(boost::asio::bind_executor(strand_, boost::bind(&printer::print2, this))); } } private: boost::asio::strand strand_; boost::asio::steady_timer timer1_; boost::asio::steady_timer timer2_; int count_; }; ``` -------------------------------- ### Implement Operation Timeouts with io_context::run_for Source: https://context7.com/boostorg/asio/llms.txt Use `run_for()` to limit the event loop execution time, enabling operation timeouts. If the timeout occurs before completion, operations are cancelled. ```cpp #include #include using boost::asio::ip::tcp; class timeout_client { public: void connect(const std::string& host, const std::string& service, std::chrono::steady_clock::duration timeout) { auto endpoints = tcp::resolver(io_context_).resolve(host, service); boost::system::error_code error; boost::asio::async_connect(socket_, endpoints, [&](const boost::system::error_code& ec, const tcp::endpoint&) { error = ec; }); run(timeout); if (error) throw boost::system::system_error(error); } private: void run(std::chrono::steady_clock::duration timeout) { io_context_.restart(); io_context_.run_for(timeout); if (!io_context_.stopped()) { // Timed out - cancel the operation socket_.close(); io_context_.run(); // Let cancellation complete } } boost::asio::io_context io_context_; tcp::socket socket_{io_context_}; }; int main() { try { timeout_client client; client.connect("www.google.com", "80", std::chrono::seconds(5)); std::cout << "Connected!\n"; } catch (std::exception& e) { std::cerr << "Error: " << e.what() << "\n"; } return 0; } ```