这是我的第一个boost::asio
项目,我想出了一个代码结构,它有一个服务器根据连接请求创建几个会话。C++ boost:asio当会话类被删除时服务器类会发生什么
会话有超时机制,我控制如果我收到来自客户端的消息。如果一段时间后客户端没有发送消息,会话将自行删除,客户端将重新启动连接以发送其数据。 - 这是预期的行为。客户是小型的远程单位。
这种机制工作正常,但我不明白在超时删除会话后该怎么办。
这里是服务器StartAccept
和服务器的HandleAccept
功能:
void SocketServer::StartAccept()
{
std::shared_ptr<SocketSession> session = std::make_shared<SocketSession>(ioService);
acceptor.listen();
acceptor.async_accept(session->getSessionSocket(), boost::bind(&SocketServer::HandleAccept, this, session, boost::asio::placeholders::error));
}
void SocketServer::HandleAccept(std::shared_ptr<SocketSession> session, const boost::system::error_code& errorCode)
{
if (errorCode)
{
std::cout << "Error accepting incoming connection: Error: " << boost::system::system_error(errorCode).what();
}
else
{
boost::asio::ip::tcp::socket& socket = session->getSessionSocket();
session->start();
}
StartAccept();
}
会议本身具有下面的代码:
void SocketSession::start()
{
readTimeout.expires_from_now(boost::posix_time::seconds(10));
readTimeout.async_wait(boost::bind(&SocketSession::TimeoutHandler, shared_from_this(), boost::asio::placeholders::error));
sessionSocket.async_read_some(boost::asio::buffer(readBuffer, MAX_BUFFER_LENGTH), boost::bind(&SocketSession::HandleRead, shared_from_this(), boost::asio::placeholders::bytes_transferred, boost::asio::placeholders::error));
}
void SocketSession::HandleRead(size_t bytesTransferred, const boost::system::error_code& errorCode)
{
readTimeout.expires_from_now(boost::posix_time::seconds(10));
if (errorCode)
{
ss << "Error reading data from session: Error: " << boost::system::system_error(errorCode).what();
delete this; <<<------- PROBLEM HERE
}
else
{
std::string data(readBuffer, bytesTransferred);
std::cout << "Data read:" << data << std::endl;
start();
}
}
当超时被触发,代码达到delete this
中,对象被破坏(我已经记录在对象析构函数中)并且整个程序在Coliru中进入 double free or corruption (out): 0x0000000000e6d5c0 *** Aborted (core dumped)
(在我的电脑中)或*** glibc detected *** ./a.out: munmap_chunk(): invalid pointer: 0x00000000020e0140 *** ==
。
我对这里发生的事情感到困惑。我是Coliru - link here的代码的完整版本。
我期望的是继续运行服务器,等待新的连接,即使有一个或多个会话超时。
帮助赞赏。
不要'删除这个;'。只是不。 – UmNyobe
嗡嗡声..不是'HandleRead'会在'boost'里面永远存在吗?在一些'boost'例子中,他们使用'delete this'“自杀”。请记住,我在每个连接请求中都会打开新会话,如果此对象在一段时间内没有被删除,我将在其附近提供相当数量的处理程序... – Mendes
请在评论中链接这些示例。 – UmNyobe