Reputation: 18561
I´m writing my first boost::asio
async server and here is the code I put together:
SocketServer.hpp
class SocketServer {
public:
SocketServer(boost::asio::io_service& ioService);
virtual ~SocketServer();
void StartAsync(int port);
void StopAsync();
private:
void StartAccept();
void HandleAccept();
boost::asio::ip::tcp::acceptor acceptor;
std::shared_ptr<boost::asio::ip::tcp::socket> socket;
};
SocketServer.cpp
SocketServer::SocketServer(boost::asio::io_service &ioService) :
acceptor(ioService),
socket(new boost::asio::ip::tcp::socket(ioService)) {}
SocketServer::~SocketServer() {}
void SocketServer::StartAsync(int port)
{
boost::asio::ip::tcp::endpoint ep(boost::asio::ip::tcp::v4(), port);
acceptor.open(ep.protocol());
StartAccept();
}
void SocketServer::StopAsync()
{
acceptor.cancel();
}
void SocketServer::StartAccept()
{
acceptor.async_accept(*socket, std::bind(&SocketServer::HandleAccept, this));
}
void SocketServer::HandleAccept()
{
std::cout << "Connection accepted." << std::endl;
std::cout << "Connection accepted from " << socket->remote_endpoint().address().to_string() << std::endl;
// Will create a new thread here to process this connection
StartAccept();
}
The idea is to receive multiple connection requests on the given port
and open for each connection a thread to process.
The problem is that, even with no connection, the HandleAccept
is being called, and the remote_endpoint throws an exception as:
remote_endpoint: Bad file desciptor
I´m a bit confused here on what´s going on.
I need to be called once for each connection, so that I can start a thread with the given connection socket.
A side question: Is that the right way of doing it, using just one socket for all connections ?
Thanks for helping.
Upvotes: 0
Views: 97
Reputation: 26080
Firstly, you're missing a call to listen
; this is what actually listens for incoming connections. This should be called on your acceptor
before the call to async_accept
:
ip::tcp::endpoint ep(boost::asio::ip::tcp::v4(), port);
acceptor.listen();
acceptor.async_accept(...);
Note that the function/function object passed to async_accept
should accept a boost::system::system_error
as a parameter as well:
acceptor.async_accept(
*socket,
std::bind(&SocketServer::HandleAccept, this, boost::asio::placeholders::error)
);
Finally, you cannot use the same socket for multiple (simultaneous) connections.
Upvotes: 1