0

I am trying to write async tcp server using asio library. The sample code found on the internet works fine but i wanted to change some parts. I'm having trouble adding the code below. I guess I need to write a copy constructor somehow but I don't understand why. I think there is a mistake in writing only the handler part. Do you think the TcpConnection object is cleared from memory before it is sent to the handleAccept function?

acceptor_.async_accept(connection.getSocket(), 
                        boost::bind(&TcpServer::handleAccept, 
                        this, connection,
                        asio::placeholders::error));

Full code:

#include <asio.hpp>
#include <boost/bind/bind.hpp>
#include <functional>
#include <vector>
#include <string>
#include <iostream>


using asio::ip::tcp;

class TcpConnection {
    using DisconnectCallback = std::function<void()>;

    int id_;
    tcp::socket socket_;
    DisconnectCallback disconnectListener_;

public:
    TcpConnection(int id, asio::io_service& io_service): id_(id), socket_(io_service) {
        std::cout << "New connection(" << id << ") created" << std::endl;
    }

    void subDisconnectListener(DisconnectCallback cb) {
        disconnectListener_ = cb;
    }

    int getId() {
        return id_;
    }

    tcp::socket& getSocket() {
        return socket_;
    }
};

class TcpServer {
private:
    int lastClientId = 0;
    asio::io_service& io_service_;
    tcp::acceptor acceptor_;

    void startAccept() {
        TcpConnection connection(++lastClientId, io_service_);
        //=========> Problem part
        acceptor_.async_accept(connection.getSocket(), 
                                boost::bind(&TcpServer::handleAccept, 
                                this, connection,
                                asio::placeholders::error));
    }

    void handleAccept(TcpConnection& connection, const asio::error_code& error) {
        if ( !error ) {
        }
        startAccept();
    }

public:
    TcpServer(asio::io_service& io_service): 
                    io_service_(io_service), 
                    acceptor_(io_service, tcp::endpoint(tcp::v4(), 13)) {
        startAccept();
    }

};

int main() {
    try {
        std::cout << "Server starting.." << std::endl;
        asio::io_service io_service;
        TcpServer server(io_service);
        io_service.run();
    } catch (std::exception& e) {
        std::cerr << e.what() << std::endl;
    }

    return 0;
}

Error:

asiosocker2.cpp: In member function ‘void TcpServer::startAccept()’:
asiosocker2.cpp:47:58: error: use of deleted function ‘TcpConnection::TcpConnection(const TcpConnection&)’
   47 |                                 asio::placeholders::error));
      |                                                          ^
asiosocker2.cpp:11:7: note: ‘TcpConnection::TcpConnection(const TcpConnection&)’ is implicitly deleted because the default definition would be ill-formed:
   11 | class TcpConnection {
      |       ^~~~~~~~~~~~~
asiosocker2.cpp:11:7: error: use of deleted function ‘asio::basic_stream_socket<asio::ip::tcp>::basic_stream_socket(const asio::basic_stream_socket<asio::ip::tcp>&)’
In file included from /usr/include/asio/basic_socket_streambuf.hpp:25,
                 from /usr/include/asio/basic_socket_iostream.hpp:24,
                 from /usr/include/asio.hpp:29,
                 from asiosocker2.cpp:1:
/usr/include/asio/basic_stream_socket.hpp:48:7: note: ‘asio::basic_stream_socket<asio::ip::tcp>::basic_stream_socket(const asio::basic_stream_socket<asio::ip::tcp>&)’ is implicitly declared as deleted because ‘asio::basic_stream_socket<asio::ip::tcp>’ declares a move constructor or move assignment operator
   48 | class basic_stream_socket
      |       ^~~~~~~~~~~~~~~~~~~
In file included from /usr/include/boost/bind/bind.hpp:2187,
                 from asiosocker2.cpp:2:
/usr/include/boost/bind/bind_mf_cc.hpp:113:86: note:   initializing argument 3 of ‘boost::_bi::bind_t<R, boost::_mfi::mf2<R, T, A1, A2>, typename boost::_bi::list_av_3<A1, A2, A3>::type> boost::bind(R (T::*)(B1, B2), A1, A2, A3) [with R = void; T = TcpServer; B1 = TcpConnection&; B2 = const std::error_code&; A1 = TcpServer*; A2 = TcpConnection; A3 = boost::arg<1> (*)(); typename boost::_bi::list_av_3<A1, A2, A3>::type = boost::_bi::list3<boost::_bi::value<TcpServer*>, boost::_bi::value<TcpConnection>, boost::arg<1> (*)()>]’
  113 |     BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3)
Qwe Qwe
  • 399
  • 4
  • 13

0 Answers0