假设我有一个套接字:
std::shared_ptr<tcp::socket> socket( new tcp::socket(acceptor.get_io_service()) );
acceptor.async_accept( *socket, std::bind( handleAccept, this, std::placeholders::_1, socket, std::ref(acceptor)) );
我将所述插座的weak_ptr存储在容器中。我需要这个,因为我想允许客户端请求其他客户端的列表,以便它们可以相互发送消息。
clients_.insert(socket); // pseudocode
然后我运行一些异步操作
socket->async_receive( boost::asio::buffer(&(*header), sizeof(Header))
, 0
, std::bind(handleReceiveHeader, this, std::placeholders::_1, std::placeholders::_2, header, socket));
如何检测连接何时关闭,以便从容器中删除套接字?
clients_.erase(socket); // pseudocode
TCP 套接字断开连接通常由eof
或connection_reset
以asio
表示。
void async_receive(boost::system::error_code const& error,
size_t bytes_transferred)
{
if ((boost::asio::error::eof == error) ||
(boost::asio::error::connection_reset == error))
{
// handle the disconnect.
}
else
{
// read the data
}
}
我使用 boost::signals2
来发出断开连接的信号,尽管您始终可以将指向函数的指针传递给您的套接字类,然后调用它。
请注意套接字和回调生存期,请参阅: boost-async-functions-and-shared-ptrs
有很多选择,其中一些是:
-
当您将
weak_ptr
存储在容器中时 - 它不会延长套接字的使用寿命,因此当您的处理程序boost::asio::error::eof
(或其他什么)时,它不会复制/移动shared_ptr
,并且套接字将被删除(如果您没有任何其他人shared_ptr
它)。因此,您可以执行以下操作:if(socket.expired()) clients_.erase(socket);
-
检查处理程序中的错误代码 - 它将指示连接何时关闭。使用此信息 - 您可以从处理程序本身调用
clients_.erase
。
你能举一个#2的例子吗?
它将是这样的:
socket->async_receive
(
boost::asio::buffer(&(*header), sizeof(Header)), 0,
[=, &clients_](const system::error_code& error, size_t bytes_transferred)
{
if(error) // or some specific code
{
clients_.erase(socket); // pseudocode
}
else
{
// continue, launch new operation, etc
}
}
);