C++ boost::shared_ptr没有类类型

C++ boost::shared_ptr没有类类型,c++,c++11,boost,C++,C++11,Boost,我已经使用BoostASIO实现了tcp客户端和tcp服务器。代码如下所示(test.cpp、test.hpp和makefile) 可执行文件可以作为 (服务器端) (客户端) tcp_服务器为连接到服务器的每个客户端使用一个holder类tcp_连接。我在tcp_连接类中添加了一个类型为的std::vector(在下面的代码中添加) 而在tcp\u服务器内部::start\u acceptI do new\u connection->get\u subscriber\u list.insert

我已经使用BoostASIO实现了tcp客户端和tcp服务器。代码如下所示<代码>(test.cpp、test.hpp和makefile)

可执行文件可以作为

(服务器端)

(客户端)

tcp_服务器
为连接到服务器的每个客户端使用一个holder类
tcp_连接
。我在tcp_连接类中添加了一个类型为的
std::vector
(在下面的代码中添加)

而在
tcp\u服务器内部::start\u accept
I do

new\u connection->get\u subscriber\u list.insert(new\u connection)

我得到了错误:new\u connection.boost::shared\u ptr::operator->()->tcp\u connection::get\u subscriber\u list'没有类类型

test.cpp

#include "test.hpp"
#include <iostream>
#include <exception>
#include <boost/array.hpp>
#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <algorithm>
#include <sstream>
#include <iomanip>

const int ARG_COUNT = 2;
const int MAX_PACKETS = 25;
const int LOWEST_PORT = 1024;
const int HIGHEST_PORT = 65000;

static char message_array[8192];

void gen_random_string(char *s, const int len)
{
    static const char alphanum[] =
        "0123456789"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "abcdefghijklmnopqrstuvwxyz";

    for (int i = 0; i < len; ++i) {
        s[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
    }
    s[len] = 0;
}

class tcp_connection :public boost::enable_shared_from_this<tcp_connection>
{
public:
    typedef boost::shared_ptr<tcp_connection> pointer;

    static pointer create(boost::asio::io_service& io_service)
    {
        return pointer(new tcp_connection(io_service));
    }

    boost::asio::ip::tcp::tcp::socket& socket()
    {
        return socket_;
    }

    void start()
    {
        gen_random_string(message_array, 8192);
        std::string message(message_array);

        boost::asio::async_write(socket_, boost::asio::buffer(message),
                                 boost::bind(&tcp_connection::handle_write, shared_from_this(),
                                             boost::asio::placeholders::error,
                                             boost::asio::placeholders::bytes_transferred));
    }

private:
    tcp_connection(boost::asio::io_service& io_service)
        : socket_(io_service)
    {
    }

    void handle_write(const boost::system::error_code& /*error*/,
                      size_t /*bytes_transferred*/)
    {
    }

    boost::asio::ip::tcp::socket socket_;
    std::vector<pointer> m_subscribe;
    std::string message;
};

class tcp_server
{
public:
    tcp_server(boost::asio::io_service& io_service,int port_number)
        : acceptor_(io_service, boost::asio::ip::tcp::tcp::endpoint(boost::asio::ip::tcp::tcp::v4(), port_number))
    {
        std::cout << "TCP server listening on " << port_number << std::endl;
        start_accept();
    }

private:
    void start_accept()
    {
        tcp_connection::pointer new_connection =
            tcp_connection::create(acceptor_.get_io_service());

        acceptor_.async_accept(new_connection->socket(),
                               boost::bind(&tcp_server::handle_accept, this, new_connection,
                                           boost::asio::placeholders::error));
    }

    void handle_accept(tcp_connection::pointer new_connection,
                       const boost::system::error_code& error)
    {
        if (!error)
        {
            new_connection->start();
            start_accept();
        }
    }

    boost::asio::ip::tcp::tcp::acceptor acceptor_;
};


void runTCPServer ( CmdLineOpts input )
{
    try
    {
        boost::asio::io_service io_service;
        tcp_server server(io_service,input.port);
        io_service.run();
    }
    catch (std::exception& e)
    {
        std::cerr << e.what() << std::endl;
    }
}

class tcp_client
{
public:
    tcp_client(
        boost::asio::io_service& io_service,
        const std::string& host,
        const std::string& port
    ) : io_service_(io_service), socket_(io_service, boost::asio::ip::tcp::tcp::endpoint(boost::asio::ip::tcp::tcp::v4(), 0))
    {
        boost::asio::ip::tcp::tcp::resolver resolver(io_service_);
        boost::asio::ip::tcp::tcp::resolver::query query(boost::asio::ip::tcp::tcp::v4(), host, port);
        boost::asio::ip::tcp::tcp::resolver::iterator iter = resolver.resolve(query);
        endpoint_ = *iter;
        boost::asio::connect(socket_, iter);
    }

    ~tcp_client()
    {
        socket_.close();
    }


    void recieve_from() {
        /*Initialize our endpoint*/
        size_t len = socket_.read_some(
                         boost::asio::buffer(recv_buf), error);

        if (error == boost::asio::error::eof)
            std::cout << "Connction close cleanly by peer" << std::cout;
        else if (error)
            throw boost::system::system_error(error); // Some other error.

        std::cout.write(recv_buf.data(), len) << std::endl;

    }

private:
    boost::asio::io_service& io_service_;
    boost::asio::ip::tcp::tcp::socket socket_;
    boost::asio::ip::tcp::tcp::endpoint endpoint_;
    boost::array<char, 2048> recv_buf;
    boost::asio::ip::tcp::endpoint sender_endpoint;
    boost::system::error_code error;

};

void runTCPClient(std::string portStr)
{
    try
    {
        boost::asio::io_service io_service;
        tcp_client client(io_service, "localhost", portStr);
        client.recieve_from();
    }
    catch (std::exception& e)
    {
        std::cerr << e.what() << std::endl;
    }

}

void runClient( CmdLineOpts input )
{
    runTCPClient(input.portStr);

}

void runServer( CmdLineOpts input )
{
    runTCPServer(input);
}

/**
 * * Usage: client_server <protocol> <port> <num of packets>
 * */
bool cmdline_parse ( int argc, char *argv[], CmdLineOpts *input )
{
    bool result = true;
    if (argc - 1 == ARG_COUNT)
    {
        // arg 1: server or client
        int arg1 = std::stoi(argv[1]);
        if (arg1 == 0 || arg1 == 1)
        {
            input->servOrClient = arg1;
        }
        else
        {
            std::cout << "Invalid client server choice.\nUsage: client_server <client (0) or server(1)> <protocol> <port>" << std::endl;
            result = false;
        }
        // arg 3: port
        int arg2 = std::stoi(argv[2]);
        if (arg2 > LOWEST_PORT && arg2 < HIGHEST_PORT )
        {
            input->port = arg2;
            input->portStr = argv[2];
        }
        else
        {
            std::cout << "Invalid port, must be between " << LOWEST_PORT << " and " << HIGHEST_PORT << std::endl;
            std::cout << "Usage: client_server <client (0) or server(1)> <protocol> <port>" << std::endl;
            result = false;
        }

    }
    else
    {
        std::cout << "Usage: client_server <client (0) or server(1)> <protocol> <port>" << std::endl;
        result = false;
    }

    return result;
}



int main ( int argc, char *argv[] )
{
    CmdLineOpts input;
    if (cmdline_parse(argc, argv, &input))
    {
        if(input.servOrClient == 1)
        {
            runServer(input);
        }
        else if(input.servOrClient == 0)
        {
            runClient(input);
        }
    }
    else
    {
        return 1;
    }

    return 0;
}
#包括“test.hpp”
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
常数int ARG_COUNT=2;
const int MAX_PACKETS=25;
const int最低_端口=1024;
最高端口常数=65000;
静态字符消息_数组[8192];
void gen_random_字符串(char*s,const int len)
{
静态常量字符alphanum[]=
"0123456789"
“ABCDEFGHIJKLMNOPQRSTUVWXYZ”
“abcdefghijklmnopqrstuvwxyz”;
对于(int i=0;i那可能是因为你写了

new_connection->get_subscriber_list.insert(new_connection);
而不是

new_connection->get_subscriber_list().insert(new_connection);
--也就是说,您试图调用
get\u subscriber\u list
函数本身上的
insert
函数,而不是调用
get\u subscriber\u list
,然后在其返回值上调用
insert


我不确定
new\u connection->get\u subscriber\u list
的类型是什么,如果有的话,但它肯定不是类类型,因此出现了错误。

我修复了现在我得到的
错误:调用'std::vector::insert(tcp\u connection::pointer&)没有匹配的函数“
错误。但文档告诉我insert用于std::vector@liv2hak您可能正在寻找的函数名为
push_-back
@liv2hak
insert
确实存在,但它需要一个迭代器来说明插入的位置。
push_-back(elem)
insert(end(),elem)
相同。
std::vector<tcp_connection::pointer> &tcp_connection::get_subscriber_list()
{
      return m_subscribers;
}
#include "test.hpp"
#include <iostream>
#include <exception>
#include <boost/array.hpp>
#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <algorithm>
#include <sstream>
#include <iomanip>

const int ARG_COUNT = 2;
const int MAX_PACKETS = 25;
const int LOWEST_PORT = 1024;
const int HIGHEST_PORT = 65000;

static char message_array[8192];

void gen_random_string(char *s, const int len)
{
    static const char alphanum[] =
        "0123456789"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "abcdefghijklmnopqrstuvwxyz";

    for (int i = 0; i < len; ++i) {
        s[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
    }
    s[len] = 0;
}

class tcp_connection :public boost::enable_shared_from_this<tcp_connection>
{
public:
    typedef boost::shared_ptr<tcp_connection> pointer;

    static pointer create(boost::asio::io_service& io_service)
    {
        return pointer(new tcp_connection(io_service));
    }

    boost::asio::ip::tcp::tcp::socket& socket()
    {
        return socket_;
    }

    void start()
    {
        gen_random_string(message_array, 8192);
        std::string message(message_array);

        boost::asio::async_write(socket_, boost::asio::buffer(message),
                                 boost::bind(&tcp_connection::handle_write, shared_from_this(),
                                             boost::asio::placeholders::error,
                                             boost::asio::placeholders::bytes_transferred));
    }

private:
    tcp_connection(boost::asio::io_service& io_service)
        : socket_(io_service)
    {
    }

    void handle_write(const boost::system::error_code& /*error*/,
                      size_t /*bytes_transferred*/)
    {
    }

    boost::asio::ip::tcp::socket socket_;
    std::vector<pointer> m_subscribe;
    std::string message;
};

class tcp_server
{
public:
    tcp_server(boost::asio::io_service& io_service,int port_number)
        : acceptor_(io_service, boost::asio::ip::tcp::tcp::endpoint(boost::asio::ip::tcp::tcp::v4(), port_number))
    {
        std::cout << "TCP server listening on " << port_number << std::endl;
        start_accept();
    }

private:
    void start_accept()
    {
        tcp_connection::pointer new_connection =
            tcp_connection::create(acceptor_.get_io_service());

        acceptor_.async_accept(new_connection->socket(),
                               boost::bind(&tcp_server::handle_accept, this, new_connection,
                                           boost::asio::placeholders::error));
    }

    void handle_accept(tcp_connection::pointer new_connection,
                       const boost::system::error_code& error)
    {
        if (!error)
        {
            new_connection->start();
            start_accept();
        }
    }

    boost::asio::ip::tcp::tcp::acceptor acceptor_;
};


void runTCPServer ( CmdLineOpts input )
{
    try
    {
        boost::asio::io_service io_service;
        tcp_server server(io_service,input.port);
        io_service.run();
    }
    catch (std::exception& e)
    {
        std::cerr << e.what() << std::endl;
    }
}

class tcp_client
{
public:
    tcp_client(
        boost::asio::io_service& io_service,
        const std::string& host,
        const std::string& port
    ) : io_service_(io_service), socket_(io_service, boost::asio::ip::tcp::tcp::endpoint(boost::asio::ip::tcp::tcp::v4(), 0))
    {
        boost::asio::ip::tcp::tcp::resolver resolver(io_service_);
        boost::asio::ip::tcp::tcp::resolver::query query(boost::asio::ip::tcp::tcp::v4(), host, port);
        boost::asio::ip::tcp::tcp::resolver::iterator iter = resolver.resolve(query);
        endpoint_ = *iter;
        boost::asio::connect(socket_, iter);
    }

    ~tcp_client()
    {
        socket_.close();
    }


    void recieve_from() {
        /*Initialize our endpoint*/
        size_t len = socket_.read_some(
                         boost::asio::buffer(recv_buf), error);

        if (error == boost::asio::error::eof)
            std::cout << "Connction close cleanly by peer" << std::cout;
        else if (error)
            throw boost::system::system_error(error); // Some other error.

        std::cout.write(recv_buf.data(), len) << std::endl;

    }

private:
    boost::asio::io_service& io_service_;
    boost::asio::ip::tcp::tcp::socket socket_;
    boost::asio::ip::tcp::tcp::endpoint endpoint_;
    boost::array<char, 2048> recv_buf;
    boost::asio::ip::tcp::endpoint sender_endpoint;
    boost::system::error_code error;

};

void runTCPClient(std::string portStr)
{
    try
    {
        boost::asio::io_service io_service;
        tcp_client client(io_service, "localhost", portStr);
        client.recieve_from();
    }
    catch (std::exception& e)
    {
        std::cerr << e.what() << std::endl;
    }

}

void runClient( CmdLineOpts input )
{
    runTCPClient(input.portStr);

}

void runServer( CmdLineOpts input )
{
    runTCPServer(input);
}

/**
 * * Usage: client_server <protocol> <port> <num of packets>
 * */
bool cmdline_parse ( int argc, char *argv[], CmdLineOpts *input )
{
    bool result = true;
    if (argc - 1 == ARG_COUNT)
    {
        // arg 1: server or client
        int arg1 = std::stoi(argv[1]);
        if (arg1 == 0 || arg1 == 1)
        {
            input->servOrClient = arg1;
        }
        else
        {
            std::cout << "Invalid client server choice.\nUsage: client_server <client (0) or server(1)> <protocol> <port>" << std::endl;
            result = false;
        }
        // arg 3: port
        int arg2 = std::stoi(argv[2]);
        if (arg2 > LOWEST_PORT && arg2 < HIGHEST_PORT )
        {
            input->port = arg2;
            input->portStr = argv[2];
        }
        else
        {
            std::cout << "Invalid port, must be between " << LOWEST_PORT << " and " << HIGHEST_PORT << std::endl;
            std::cout << "Usage: client_server <client (0) or server(1)> <protocol> <port>" << std::endl;
            result = false;
        }

    }
    else
    {
        std::cout << "Usage: client_server <client (0) or server(1)> <protocol> <port>" << std::endl;
        result = false;
    }

    return result;
}



int main ( int argc, char *argv[] )
{
    CmdLineOpts input;
    if (cmdline_parse(argc, argv, &input))
    {
        if(input.servOrClient == 1)
        {
            runServer(input);
        }
        else if(input.servOrClient == 0)
        {
            runClient(input);
        }
    }
    else
    {
        return 1;
    }

    return 0;
}
#ifndef CLIENT_SERVER_H_INCLUDED                                                                                                                                                                                   
#define CLIENT_SERVER_H_INCLUDED

#include <string>

struct CmdLineOpts
{
    std::string portStr;
    int port;
    int servOrClient;
};

void runTCPServer ( CmdLineOpts input );

void runTCPClient ( std::string port_str);

bool cmdline_parse ( int argc, char *argv[], CmdLineOpts input );
#endif
TARGET = client_server                                                                                                                                                                                             
LIBS = -lboost_system -lpthread
CXX = g++ 
CXXFLAGS = -std=c++11 -g -Wall -pedantic

.PHONY: default all clean

default: $(TARGET)
all: default

OBJECTS = $(patsubst %.cpp, %.o, $(wildcard *.cpp))
HEADERS = $(wildcard *.hpp)

%.o: %.cpp $(HEADERS)
  $(CXX) $(CXXFLAGS) -c $< -o $@

.PRECIOUS: $(TARGET) $(OBJECTS)

$(TARGET): $(OBJECTS)
  $(CXX) $(OBJECTS) $(LIBS) -o $@

clean:
      -rm -f *.o
      -rm -f $(TARGET)
new_connection->get_subscriber_list.insert(new_connection);
new_connection->get_subscriber_list().insert(new_connection);