没有类的boost asio简单回显服务器 [英] boost asio simple echo server without class

查看:98
本文介绍了没有类的boost asio简单回显服务器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习boost :: asio,我只想要一个简单的回显服务器和一个异步模式且没有类的客户端.我学会了如何使用select在winsock2中使用异步模式,但是我无法理解boost :: asio异步工作的每个步骤.请创建一个简单的echo服务器,逐步调用所需的回调函数以接受连接,简单地读写套接字.

I'm learning boost::asio and I just want a simple echo server and a client in asynchronous mode without classes. I learned how to work with an asynchronous mode in winsock2 with select, but I can`t understand every step of boost::asio's async work. Please make a simple echo server that step by step calls needed callback functions accepts connections, reads and writes to a socket simply.

提前谢谢

推荐答案

仅因为一个好的示例将证明它无济于事,所以这里是您的无类回显服务器.

Just because a good sample will demonstrate that it won't help, here's your class-less echo server.

它也是:

  • 无线程
  • 异步
  • 多会话

在Coliru上直播

#include <boost/asio.hpp>
#include <iostream>

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<tcp::socket>;

    std::function<void()>        do_accept;
    std::function<void(session)> do_session;

    do_session = [&](session s) {
        // do a read
        auto buf = std::make_shared<std::vector<char>>(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<session::element_type>(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)
}

奖金

因为今天是让我们再次使用协程"的日子,所以这里是使用boost::asio::spawn的版本:

在Coliru上直播

#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>
#include <iostream>

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)
}

这篇关于没有类的boost asio简单回显服务器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆