【问题标题】:moving Boost asio TCP stream移动 Boost asio TCP 流
【发布时间】:2018-03-12 09:25:05
【问题描述】:

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

我使用的设计模式是:

  1. 服务器初始化boost::asio::ip::tcp::acceptorboost::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 没有移动 ctor。这可以防止编译 std::swap()new Session() 行。

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

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

【问题讨论】:

    标签: c++ sockets boost tcp boost-asio


    【解决方案1】:

    只需将您的会话包装在一个共享指针中: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。里面还有会话类。

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

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

    【讨论】:

    • 哇,不知道 boost 在 1.66 中添加了这个重载。仍在 1.62,但很高兴知道。
    猜你喜欢
    • 2012-06-06
    • 1970-01-01
    • 2018-06-08
    • 1970-01-01
    • 1970-01-01
    • 2018-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多