如何在单独的线程中启动 Boost echo 服务器

How to start Boost echo server in a separate thread

我在单独的线程运行中使用提升版本提升 1_64_0 到 运行 Tcp 服务器

这是服务器代码。

https://www.boost.org/doc/libs/1_52_0/doc/html/boost_asio/example/echo/async_tcp_echo_server.cpp

在主循环中,我可以像这样生成一个新线程。

int main()
{

// Run the boost echo server as a different thread
boost::asio::io_service io_service;
server server1(io_service, 1980);   
boost::thread t(boost::bind(&io_service::run, &io_service));    

// when about to close the program
io_service.stop(); // stop the server
t.join();
}

现在我已经将 boost 版本更改为 boost_1_73_0 并且我正在使用此示例创建服务器

https://www.boost.org/doc/libs/1_71_0/doc/html/boost_asio/example/cpp11/echo/async_tcp_echo_server.cpp

如何创建新线程?

创建新线程的现有代码出错。

  1. io_service: :: 左边必须是 class/struct/union

  2. 运行 : 未声明的标识符

&io_service::run 中,io_service 不是类型,而是该名称的局部变量。

https://www.boost.org/doc/libs/1_74_0/doc/html/boost_asio/example/cpp11/echo/async_tcp_echo_server.cpp开始

    io_context.run();

需要像

    std::thread t([&] { io_context.run(); });
    // ...
    t.join();

或者如果你坚持:

    std::thread t(boost::bind(&boost::asio::io_context::run, &io_context));

我会使用 thread_pool 来简化所有的复杂性¹:

    boost::asio::thread_pool io(1);

    server s(io.get_executor(), std::atoi(argv[1]));

    // ...
    io.join();

需要对 class 界面进行简单的编辑(参见

Live On Coliru

//
// async_tcp_echo_server.cpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// 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.hpp>
#include <boost/bind/bind.hpp>
#include <cstdlib>
#include <iostream>
#include <memory>
#include <utility>

using boost::asio::ip::tcp;

class session : public std::enable_shared_from_this<session> {
  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 /*length*/) {
                if (!ec) {
                    do_read();
                }
            });
    }

    tcp::socket socket_;
    enum { max_length = 1024 };
    char data_[max_length];
};

class server {
  public:
    template <typename Executor>
    server(Executor ex, short port)
            : acceptor_(ex, 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<session>(std::move(socket))->start();
                }

                do_accept();
            });
    }

    tcp::acceptor acceptor_;
};

int main(int argc, char* argv[]) {
    try {
        if (argc != 2) {
            std::cerr << "Usage: async_tcp_echo_server <port>\n";
            return 1;
        }

        boost::asio::thread_pool io(1);

        server s(io.get_executor(), std::atoi(argv[1]));

        // ...
        io.join();
    } catch (std::exception& e) {
        std::cerr << "Exception: " << e.what() << "\n";
    }
}

¹ 参见示例Should the exception thrown by boost::asio::io_service::run() be caught?