gpt4 book ai didi

c++ - 如何正确关闭 asio tcp 服务器?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:41:10 27 4
gpt4 key购买 nike

关闭异步 boost asio tcp 服务器的正确方法是什么?我目前的解决方案通常在析构函数中陷入僵局。为什么?

class connection;

typedef std::set<shared_ptr<connection>> connection_set;

class connection : public enable_shared_from_this<connection>
{
shared_ptr<tcp::socket> socket_;

std::array<char, 8192> data_;

shared_ptr<connection_set> connection_set_;
public:
static shared_ptr<connection> create(shared_ptr<tcp::socket> socket, shared_ptr<connection_set> connection_set)
{
auto con = shared_ptr<connection>(new connection(std::move(socket), std::move(connection_set)));
con->read_some();
return con;
}

void on_next(const event& e)
{
// async_write_some ...
}

private:
connection(shared_ptr<tcp::socket> socket, shared_ptr<connection_set> connection_set)
: socket_(std::move(socket))
, connection_set_(std::move(connection_set))
{
}

void handle_read(const boost::system::error_code& error, size_t bytes_transferred)
{
if(!error)
{
on_read(std::string(data_.begin(), data_.begin() + bytes_transferred));
read_some();
}
else if (error != boost::asio::error::operation_aborted)
connection_set_->erase(shared_from_this());
else
read_some();
}

void handle_write(const shared_ptr<std::vector<char>>& data, const boost::system::error_code& error, size_t bytes_transferred)
{
if(!error)
{
}
else if (error != boost::asio::error::operation_aborted)
connection_set_->erase(shared_from_this());
}

void read_some()
{
socket_->async_read_some(boost::asio::buffer(data_.data(), data_.size()), std::bind(&connection::handle_read, shared_from_this(), std::placeholders::_1, std::placeholders::_2));
}

void on_read(std::string str)
{
// parse the string...
}
};

class tcp_observer
{
boost::asio::io_service service_;
tcp::acceptor acceptor_;
std::shared_ptr<connection_set> connection_set_;
boost::thread thread_;

public:
tcp_observer(unsigned short port)
: acceptor_(service_, tcp::endpoint(tcp::v4(), port))
, thread_(std::bind(&boost::asio::io_service::run, &service_))
{
start_accept();
}

~tcp_observer()
{
// Deadlocks...
service_.post([=]
{
acceptor_.close();
connection_set_->clear();
});
thread_.join();
}

void on_next(const event& e)
{
service_.post([=]
{
BOOST_FOREACH(auto& connection, *connection_set_)
connection->on_next(e);
});
}
private:
void start_accept()
{
auto socket = std::make_shared<tcp::socket>(service_);
acceptor_.async_accept(*socket, std::bind(&tcp_observer::handle_accept, this, socket, std::placeholders::_1));
}

void handle_accept(const shared_ptr<tcp::socket>& socket, const boost::system::error_code& error)
{
if (!acceptor_.is_open())
return;

if (!error)
connection_set_->insert(connection::create(socket, connection_set_));

start_accept();
}
};

最佳答案

这个“死锁”是因为连接不会被破坏,因为在传递 shared_from_this() 的地方仍有待处理的操作。

调用每个连接的套接字 shutdown(..) 和 close(..)。然后等待完成,这会发出 eof 或 operation_aborted 信号。

关于c++ - 如何正确关闭 asio tcp 服务器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9207441/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com