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)