boost asio serveur d’écho simple sans classe

J’apprends boost :: asio et je veux juste un serveur d’écho simple et un client en mode asynchrone sans classes. J’ai appris à travailler avec un mode asynchrone dans Winsock2 avec select, mais je ne peux pas comprendre toutes les étapes du travail async de boost :: asio. Faites un serveur d’écho simple qui appelle pas à pas les fonctions de rappel nécessaires, accepte les connexions, lit et écrit simplement sur un socket.

Merci d’avance

Juste parce qu’un bon échantillon montrera que cela ne va pas aider, voici votre serveur d’écho sans classe.

C’est aussi:

  • sans fil
  • async
  • multi-session

Live On Coliru

#include  #include  using boost::asio::ip::tcp; using boost::system::error_code; using boost::asio::streambuf; int main() { boost::asio::io_service svc; tcp::acceptor a(svc); a.open(tcp::v4()); a.set_option(tcp::acceptor::reuse_address(true)); a.bind({{}, 6767}); // bind to port 6767 on localhost a.listen(5); using session = std::shared_ptr; std::function do_accept; std::function do_session; do_session = [&](session s) { // do a read auto buf = std::make_shared>(1024); s->async_read_some(boost::asio::buffer(*buf), [&,s,buf](error_code ec, size_t bytes) { if (ec) std::cerr << "read failed: " << ec.message() << "\n"; else { std::cout << "Echo to " << s->remote_endpoint(ec) << ": " << std::string(buf->data(), bytes); if (ec) std::cerr << "endpoint failed: " << ec.message() << "\n"; else async_write(*s, boost::asio::buffer(*buf), [&,s,buf](error_code ec, size_t) { if (ec) std::cerr << "write failed: " << ec.message() << "\n"; }); do_session(s); // full duplex, can read while writing, using a second buffer } }); }; do_accept = [&] { auto s = std::make_shared(svc); a.async_accept(*s, [&,s](error_code ec) { if (ec) std::cerr << "accept failed: " << ec.message() << "\n"; else { do_session(s); do_accept(); // accept the next } }); }; do_accept(); // kick-off svc.run(); // wait for shutdown (Ctrl-C or failure) } 

PRIME

Parce que le jour d'aujourd'hui "réutilisons les coroutines", voici une version utilisant boost::asio::spawn :

Live On Coliru

 #include  #include  #include  namespace ba = boost::asio; using ba::ip::tcp; using ba::yield_context; int main() { ba::io_service svc; tcp::acceptor a(svc); a.open(tcp::v4()); a.set_option(tcp::acceptor::reuse_address(true)); a.bind({{}, 6767}); // bind to port 6767 on localhost a.listen(5); spawn(svc, [&a](yield_context yield) { while(1) { tcp::socket s(a.get_io_service()); a.async_accept(s, yield); spawn(yield, [s=std::move(s)](yield_context yield) mutable { // do a read char buf[1024] = {}; size_t bytes = s.async_read_some(ba::buffer(buf), yield); std::cout << "Echo to " << s.remote_endpoint() << ": " << std::string(buf, buf+bytes); bytes = async_write(s, ba::buffer(buf), yield); }); }; }); svc.run(); // wait for shutdown (Ctrl-C or failure) }