移动 Boost asio TCP 流
moving Boost asio TCP stream
我正在使用 boost::asio::ip::tcp 创建服务器,但我在使用流来执行此操作时遇到问题。
我使用的设计模式是:
- 服务器初始化 boost::asio::ip::tcp::acceptor, and a boost::asio::ip::tcp::iostream。
- 服务器使用 boost::asio::ip::tcp::acceptor, using async_accept 监听端口,接受
stream
对象。
- 当出现传入连接时,会创建一个新的
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
没有移动指令。这会阻止编译 std::swap()
或 new Session()
行。
我可以将此模式与 boost::asio::ip::tcp::socket 一起使用,因为它支持移动构造函数,但由于某些原因,流不支持它。如果我可以从套接字中提取流,那么我就可以解决这个问题,但我不知道该怎么做。
接受 TCP 流并将连接传递给处理会话的对象的最佳方法是什么?
只需将您的会话包装在一个共享指针中:std::shared_ptr<Session>
并为接收者做好准备。实例化连接后,启动其 life-circle。参见 ASIO 示例:http://www.boost.org/doc/libs/1_66_0/doc/html/boost_asio/example/cpp11/echo/async_tcp_echo_server.cpp。里面还有sessionclass
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.
的移动构造函数
我正在使用 boost::asio::ip::tcp 创建服务器,但我在使用流来执行此操作时遇到问题。
我使用的设计模式是:
- 服务器初始化 boost::asio::ip::tcp::acceptor, and a boost::asio::ip::tcp::iostream。
- 服务器使用 boost::asio::ip::tcp::acceptor, using async_accept 监听端口,接受
stream
对象。 - 当出现传入连接时,会创建一个新的
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
没有移动指令。这会阻止编译 std::swap()
或 new Session()
行。
我可以将此模式与 boost::asio::ip::tcp::socket 一起使用,因为它支持移动构造函数,但由于某些原因,流不支持它。如果我可以从套接字中提取流,那么我就可以解决这个问题,但我不知道该怎么做。
接受 TCP 流并将连接传递给处理会话的对象的最佳方法是什么?
只需将您的会话包装在一个共享指针中:std::shared_ptr<Session>
并为接收者做好准备。实例化连接后,启动其 life-circle。参见 ASIO 示例:http://www.boost.org/doc/libs/1_66_0/doc/html/boost_asio/example/cpp11/echo/async_tcp_echo_server.cpp。里面还有sessionclass
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.