我知道这个问题已经在很多其他帖子中讨论过了。 特别是this似乎与我的问题类似,并且也处理了boost :: asio,但在我的情况下,我已经有了一个shared_ptr,它拥有调用shared_from_this()的对象
有什么想法吗?
这是代码
node.h
#ifndef NODE_H_INCLUDED
#define NODE_H_INCLUDED
#include <vector>
#include <string>
#include <memory>
#include <thread>
#include <boost/asio.hpp>
#include <boost/enable_shared_from_this.hpp>
typedef boost::asio::ip::tcp::socket tcp_socket;
typedef boost::asio::ip::tcp::acceptor tcp_acceptor;
typedef std::shared_ptr<tcp_socket> tcp_socket_ptr;
class Peer;
class InConnection;
typedef std::shared_ptr<InConnection> InConnection_ptr;
class AsioNode
{
friend class InConnection;
private:
int _port;
std::vector<Peer> _peers;
std::vector<tcp_socket_ptr> _peers_connections;
boost::asio::io_service _io_service;
tcp_acceptor _acceptor;
std::thread _rcv_thread;
static const std::string inter_mex_delimiter;
void accept();
void handle_accept(InConnection_ptr new_connection, const boost::system::error_code &error);
public:
AsioNode(const std::vector<Peer> &peers, int port);
void initialize_telecom();
};
class InConnection: public boost::enable_shared_from_this<InConnection>
{
private:
tcp_socket _input_socket;
boost::asio::streambuf _input_buffer;
void handle_read(const boost::system::error_code &error, std::size_t nbytes);
public:
InConnection(boost::asio::io_service &svc) : _input_socket(svc){};
tcp_socket &socket() {return _input_socket;}
void read();
};
class Peer{
private:
int _port;
std::string _host;
public:
Peer(std::string host, int port) : _host(host), _port(port) {}
int get_port() const {return _port;}
std::string get_host() const {return _host;}
};
typedef std::shared_ptr<AsioNode> AsioNode_ptr;
#endif // NODE_H_INCLUDED
node.cpp (在方法accept()中,对于每个连接,我创建一个新的InConnection对象并将其存储在shared_ptr上)
#include <vector>
#include <string>
#include <iostream>
#include <ostream>
#include <memory>
#include <exception>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include "node.h"
void InConnection::read()
{
boost::asio::async_read_until(_input_socket, _input_buffer, AsioNode::inter_mex_delimiter,
boost::bind(&InConnection::handle_read, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}
void InConnection::handle_read(const boost::system::error_code &error, std::size_t nbytes)
{
if(!error)
{
// do things
read();
}
else
std::cout << "error in read " << error << std::endl;
}
const std::string AsioNode::inter_mex_delimiter = "end_message";
AsioNode::AsioNode(const std::vector<Peer> &peers, int port) :
_port(port), _peers(peers), _acceptor(_io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)),
_rcv_thread([&] {boost::asio::io_service::work work(_io_service); _io_service.run();})
{
accept();
}
void AsioNode::initialize_telecom()
{
boost::asio::ip::tcp::resolver resolver(_io_service);
// initialize the client side (for gossiping packets)
for (const auto &peer : _peers)
{
tcp_socket_ptr new_socket(new tcp_socket(_io_service));
boost::system::error_code ec;
auto endpoint = resolver.resolve(boost::asio::ip::tcp::resolver::query(peer.get_host(), std::to_string(peer.get_port())));
boost::asio::connect(*new_socket, endpoint, ec);
if(ec)
std::cout << "error on connetctin" << std::endl;
else{
// std::cout << _port << " connected to " << peer.get_port() << std::endl;
}
_peers_connections.push_back(new_socket);
}
}
void AsioNode::accept()
{
/*
* HERE i create the shared_ptr to the tcp connection
*
*
*/
InConnection_ptr new_connection(new InConnection(_io_service));
_acceptor.async_accept(new_connection->socket(),
boost::bind(&AsioNode::handle_accept, this, new_connection, boost::asio::placeholders::error));
}
void AsioNode::handle_accept(InConnection_ptr new_connection, const boost::system::error_code &error)
{
if(!error)
{
std::cout << _port << " accept " << new_connection->socket().remote_endpoint().port() << std::endl;
// start accepting the peer messages
new_connection->read();
}
else
std::cout << _port << " error " << error << " on accept" << std::endl;
// listen for new peer connections
accept();
}
简单的演示测试 每个节点都接受一个端口上的连接,并连接到其他三个节点
#include <iostream>
#include <vector>
#include <string>
#include "node.h"
int main()
{
std::string localhost("127.0.0.1");
int port1 = 10000;int port2 = 10001;int port3 = 10002;
Peer peer1(localhost, port1), peer2(localhost, port2), peer3(localhost, port3);
std::vector<Peer> peers1({peer2, peer3}), peers2({peer1, peer3}), peers3({peer1, peer2});
// initialize the server side
auto node1 = std::make_shared<AsioNode>(peers1, port1);
auto node2 = std::make_shared<AsioNode>(peers2, port2);
auto node3 = std::make_shared<AsioNode>(peers3, port3);
node1->initialize_telecom();
node2->initialize_telecom();
node3->initialize_telecom();
while(1);
}
答案 0 :(得分:0)
问题在于我混合命名空间 std(std :: shared_ptr)和boost(boost :: enable_shared_from_this)。
在我的情况下,我解决了从boost::enable_shared_from_this
移动到std::enable_shared_from_this