c++ - 移动 Boost asio TCP 流

标签 c++ sockets boost tcp boost-asio

我正在使用 boost::asio::ip::tcp 创建服务器,但我在使用流执行此操作时遇到问题。

我使用的设计模式是:

  1. 服务器初始化一个boost::asio::ip::tcp::acceptor , 和一个 boost::asio::ip::tcp::iostream .
  2. 服务器使用boost::asio::ip::tcp::acceptor 监听端口, 使用 async_accept , 接受到 stream 对象。
  3. 当传入连接发生时,将创建一个新的Session 对象。流对象被传递给 Session,然后我们用一个新的 iostream 对象重复步骤 2。

代码如下:

class Session; // Ctor: Session(asio::ip::tcp::stream tcp_stream)

class Server
{
public:
    Server(boost::asio::io_service& p_service, unsigned p_port) :
        m_service(p_service),
        m_acc(m_service, boost::asio::ip::tcp::endpoint( asio::ip::tcp::v4(), p_port ) )
    {
        m_acc.async_accept(
                    *m_tcp_stream.rdbuf(),
                    std::bind(&Server::AcceptHandler, this, _1)
                    );
    }

private:
    void AcceptHandler(const boost::system::error_code& p_error)
    {
        if( !p_error )
        {
            boost::asio::ip::tcp::iostream tcp_stream;
            std::swap(m_tcp_stream, tcp_stream);
            new Session( std::move(tcp_stream) );

            m_acc.async_accept(
                        *m_tcp_stream.rdbuf(),
                        std::bind(&Server::AcceptHandler, this, _1)
                        );
        }
    }

private:
    boost::asio::io_service&        m_service;
    boost::asio::ip::tcp::iostream  m_tcp_stream;
    boost::asio::ip::tcp::acceptor  m_acc;
};

我的问题是 boost::asio::ip::tcp::iostream 没有 move ctor。这会阻止编译 std::swap()new Session() 行。

我可以将此模式与 boost::asio::ip::tcp::socket 一起使用因为它支持 move ctor,但由于某些原因,流不支持它。如果我可以从套接字中提取流,那么我就可以解决这个问题,但我不知道该怎么做。

接受 TCP 流并将连接传递给处理 session 的对象的最佳方式是什么?

最佳答案

只需将您的 session 包装在一个共享指针中:std::shared_ptr<Session>并为接受者做好准备。一旦连接被实例化,就启动它的生命周期。参见 ASIO 示例:http://www.boost.org/doc/libs/1_66_0/doc/html/boost_asio/example/cpp11/echo/async_tcp_echo_server.cpp .里面还有session类。

class Server
{
public:
    Server(boost::asio::io_service& p_service, unsigned p_port) :
        m_service(p_service),
        m_acc(m_service, boost::asio::ip::tcp::endpoint( asio::ip::tcp::v4(), p_port ) ),
        m_session( std::make_shared< Session >() )
    {
        StartListen();
    }

private:
    void StartListen()
    {
            m_acc.async_accept(
                m_session->tcp_stream().rdbuf(),
                std::bind(&Server::AcceptHandler, this, _1) );
    }

    void AcceptHandler(const boost::system::error_code& p_error)
    {
        if( !p_error )
        {
            auto ses = std::make_shared< Session >();
            std::swap( ses, m_session );
            ses->InitLifeCircle(); // Start whatever logic you needed.
            StartListen();
        }
    }

private:
    boost::asio::io_service&        m_service;
    boost::asio::ip::tcp::acceptor  m_acc;
    std::shared_ptr< Session >      m_session;
};

您还可以使用最新的 boost (1.66)。它支持 boost::asio::ip::tcp::iostream 的移动构造函数http://www.boost.org/doc/libs/1_66_0/doc/html/boost_asio/reference/ip__tcp/iostream.html .

关于c++ - 移动 Boost asio TCP 流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49231769/

相关文章:

c++ - 将 const double[][] 数组作为参数传递给 double** 接口(interface)

c++ - BYTE 作为未声明的标识符,即使我包含了 windows.h

c++ - 使异步套接字服务器和客户端工作(用 C 编写)

c - 如何防止sendfile函数中的SIGPIPE

c++ - 是否有 boost::weak_intrusive_pointer?

c++ - boost asio 错误类别为空

c++ - 标准库中 boost::make_transform_iterator 的等价物是什么?

c++ - 加载 24 位 TGA

c++ - 使用 cmake 和 Qt4 进行 make 时出现 RCC 解析错误

sockets - Windows-Linux-Mac上的UDP套接字网络断开连接行为