我尝试从 boost asio 聊天示例开始并派生出一个自己的网络程序。不幸的是,我在理解到底发生了什么方面遇到了一些问题。我试图将我的程序减少到绝对最低限度。服务器类等待传入连接并创建会话对象来处理连接。这是服务器的代码:
#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();
to std::make_shared<Session>(std::move(m_oSocket));
并添加了StartSession();
在 Session 类的构造函数中。如果我运行代码,它会抛出
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 感到困惑。似乎总是做一些奇怪的事情。