我尝试从boost asio chat示例开始,并派生出一个自己的网络程序。不幸的是,我有一些问题,了解真正发生的事我试图将我的程序减少到最低限度。服务器类等待传入连接并创建会话对象以处理连接。这是服务器的代码:
#include <cstdint>
#include <iostream>
#include <sstream>
#include <memory>
#include <vector>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
class Session : public std::enable_shared_from_this<Session>
{
public:
Session(boost::asio::ip::tcp::socket __oSocket);
virtual ~Session();
void StartSession();
private:
void StartRecv();
std::vector<int32_t> m_vecSetupReceiveBuffer;
boost::asio::ip::tcp::socket m_oSocket;
};
Session::Session(boost::asio::ip::tcp::socket __oSocket) :
m_vecSetupReceiveBuffer({2}),
m_oSocket(std::move(__oSocket))
{ }
Session::~Session()
{
std::cout << "Deleted session" << std::endl;
}
void Session::StartSession()
{
auto self(shared_from_this());
std::cout << "StartSession()" << std::endl;
boost::asio::async_write(m_oSocket, boost::asio::buffer(m_vecSetupReceiveBuffer),
[this, self](boost::system::error_code _oError, std::size_t)
{
std::cout << m_vecSetupReceiveBuffer.size() << std::endl;
StartRecv();
});
}
void Session::StartRecv()
{
auto self(shared_from_this());
std::cout << "StartRecv()" << std::endl;
boost::asio::async_read(m_oSocket, boost::asio::buffer(m_vecSetupReceiveBuffer),
[this, self](boost::system::error_code _oError, std::size_t)
{});
}
class Server
{
public:
Server(boost::asio::io_service& _rIOService, uint32_t _nPort);
virtual ~Server();
private:
void StartAccept();
boost::asio::ip::tcp::acceptor m_oAcceptor;
boost::asio::ip::tcp::socket m_oSocket;
};
Server::Server(boost::asio::io_service& _rIOService, uint32_t _nPort) :
m_oAcceptor(_rIOService, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), _nPort)),
m_oSocket(_rIOService)
{
StartAccept();
}
Server::~Server()
{}
void Server::StartAccept()
{
m_oAcceptor.async_accept(m_oSocket,
[this](boost::system::error_code _oError)
{
std::make_shared<Session>(std::move(m_oSocket))->StartSession();
StartAccept();
});
}
int main(int argc, char* argv[])
{
boost::asio::io_service _oIOServerService;
std::shared_ptr<Server> _pServer(std::make_shared<Server>(_oIOServerService, 2000));
_oIOServerService.run();
return 0;
}
这段代码按预期运行,但是当我尝试调整一些东西并稍微玩一下时,我发现我不明白何时真正创建和删除共享指针以及存储它们的位置。例如,我尝试将std::make_shared<Session>(std::move(m_oSocket))->StartSession();
更改为std::make_shared<Session>(std::move(m_oSocket));
,并在Session类的构造函数中添加了StartSession();
。如果我运行代码然后抛出
terminate called after throwing an instance of 'std::bad_weak_ptr'
what(): bad_weak_ptr
Aborted (core dumped)
这可能发生在auto self(shared_from_this());
。但我不明白为什么?我应该在代码中更改什么?所以我认为我的问题是我不明白如何正确使用shared_ptr,如何在这些结构中使用它,我可以访问它以及如何使它可访问。此外,我不清楚为什么有时必须使用this
以及何时使用shared_from_this()
。是否有一个很好的教程,或简单的经验法则?
我也不清楚,为什么有些用户使用lambda函数表示法,有些用boost::bind
表示法有什么区别?
请原谅我的新手问题,我试图在教程中找到一些信息,但我只是混淆了这些共享指针和boost :: asio。似乎总是做一些奇怪的事情。
答案 0 :(得分:0)
您获得std::bad_weak_ptr
,因为在构建shared_ptr
期间没有this
拥有Session
。您仍然在make_shared
的正文中,并且尚未创建shared_ptr
。
shared_from_this()
仅在Session
的实例中可用,它是一个成员函数。您通过派生std::enable_shared_from_this
继承了它。
lambda由self
的副本构成,Session
的成员可用 - 如果this
也指向Session
对象,而不是lambda对象,因为this
捕获