c++ - io_service.run() 没有阻塞。服务器已创建,然后立即关闭

标签 c++ boost boost-asio

在我尝试自己实现完全相同的事情之前,所有的 boost 示例都有效。我开始认为必须有创建顺序或 io_service 所有权才能正确阻止事物。

我的服务器结构如下:

class Server {
  public:
    Server(unsigned short port)
    : ioService_(), acceptor_(ioService_), socket_(ioService_) { 
      acceptClient(); // begin async accept
    }

    void start(); // runs ioService_.run();

  private:

   void acceptClient();

   asio::io_service ioService_;
   tcp::acceptor acceptor_;
   tcp::socket socket_;
   Cluster cluster_; // essentially just a connection manager
};

acceptClient() 函数的工作原理如下:

void Server::acceptClient() {
  acceptor_.async_accept(socket_, [this](const system::error_code& e){
    if(!acceptor_.is_open()) return;
    if(!e) {
      cluster_.add(std::make_shared<Client>(std::move(socket_), cluster_));
    }

    acceptClient();
  });
}

我不确定您是否需要 Client 类的概述,因为即使没有客户端,服务器也应该运行和阻塞。

服务器的创建过程如下:

try {
  Server server(port);
  server.start(); // this calls the server's member io_service's run();
} catch (const std::exception& e) {
  std::cerr << e.what(); << std::endl;
}

问题是服务器在该调用后立即关闭。程序启动然后退出且没有错误。 io_service.run() 依赖什么?例如我忘记的某种形式的异步链接?我从 boost asio 的 http 服务器设计中学到了这个设计,但我已经按照我的基本目的使用它。问题是一些 boost 示例在客户端本身建立了一个新成员 boost tcp::socket 而不是将服务器移动到客户端,所以我很困惑。他们还倾向于使用 std::bind 的 boost 版本,而不是 lambda 等。

所以,任何人都可以给我简要介绍一下如何创建一个基本的、剥离的、异步服务器,因为 boost 示例真的很困惑,因为每个示例的代码约定不同。我想知道是否有人会立即注意到任何会导致我的服务器立即关闭的事情。

谢谢。

最佳答案

我测试了async_accept使用以下代码将 Hello 发送到连接到该端口的客户端。至少创建了endpoint对象,acceptor.open(endpoint.protocol()) , acceptor.bind(endpoint)acceptor.listen()您的代码中似乎缺少的调用。

#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <string>

using namespace boost::asio;

void handle_accept(
    io_service * ios,
    ip::tcp::acceptor * acceptor,
    ip::tcp::socket * socket,
    const boost::system::error_code & error)
{
    if (!error) {
        std::string msg("Hello\n");
        socket->send(buffer(msg, msg.length()));

        ip::tcp::socket * temp = new ip::tcp::socket(*ios);
        acceptor->async_accept(*temp,
                               boost::bind(handle_accept,
                                           ios, acceptor, temp,
                                           placeholders::error));
    }
}

int main(void)
{
    io_service ios;
    ip::tcp::socket socket(ios);
    ip::tcp::acceptor acceptor(ios);
    ip::tcp::endpoint endpoint(ip::tcp::v4(), 1500);
    acceptor.open(endpoint.protocol());
    acceptor.set_option(ip::tcp::acceptor::reuse_address(true));
    acceptor.bind(endpoint);
    acceptor.listen();

    acceptor.async_accept(socket,
                          boost::bind(handle_accept,
                                      &ios, &acceptor, &socket,
                                      placeholders::error));
    ios.run();

    /*
    acceptor.accept(socket);
    std::string msg("Hello\n");
    socket.send(buffer(msg, msg.length()));
    */
}

具有Server 类和lambda 作为async_accept 参数的版本:

#include <boost/asio.hpp>
#include <functional>
#include <string>

using namespace boost::asio;

class Server {
public:
    Server(unsigned short port) : ios(), acceptor(ios), socket(ios), 
                                  endpoint(ip::tcp::v4(), port) {
        acceptor.open(endpoint.protocol());
        acceptor.set_option(ip::tcp::acceptor::reuse_address(true));
        acceptor.bind(endpoint);
        acceptor.listen();
        nsocket = &socket;
    }

    void run() {
        std::function<void (const boost::system::error_code &)> f;
        f = [&f, this] (const boost::system::error_code & error) {
            if (!error) {
                std::string msg("Hello\n");
                nsocket->send(buffer(msg, msg.length()));

                nsocket = new ip::tcp::socket(ios);
                acceptor.async_accept(*nsocket, f);
            }
        };

        acceptor.async_accept(socket, f);
        ios.run();
    }

protected:
    io_service ios;
    ip::tcp::acceptor acceptor;
    ip::tcp::socket socket;
    ip::tcp::endpoint endpoint;

    ip::tcp::socket * nsocket;
};


int main(void)
{
    Server srv(1500);
    srv.run();
}

关于c++ - io_service.run() 没有阻塞。服务器已创建,然后立即关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38810209/

相关文章:

c++ - asio::async_read_until:处理多行的稳健且优雅的方式

python - 如何在不终止解释器的情况下中断 native 扩展代码?

c++ - 误解重复指令 - 它应该失败,但没有

c++ - 从 io_context 中删除工作或使用多个 io_context 对象

c++ - boost program_options 开/关标志

c++ - boost::asio::ip::tcp::socket::cancel 和 socket::close 之间有什么不同

c++ - 如何为圆环创建索引

c++ - 迭代器循环不计算最后一项

c++ - 如何使用 CMake 在 ubuntu 上找到已安装的 Boost 库?

sockets - 我可以使用 Boost.Asio 在多线程 I/O 服务超时的情况下同步读取套接字吗?