Reputation: 1082
I try to run an async network thread using boost::asio and boost::thread. But the async_accept returns immediately with error code 125 - operation canceled...
attached I a minimal sample of the Problem:
#include <iostream>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
class Server{
public:
Server()
{ }
void listen(unsigned int port)
{
boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port);
boost::asio::ip::tcp::acceptor acceptor(m_io_service, endpoint);
std::cout << "Waiting for incomming connection on port: " << port << std::endl;
acceptor.async_accept(*m_stream.rdbuf(), boost::bind( &Server::handleAccept, this, boost::asio::placeholders::error, boost::ref( acceptor ) ) );
m_listenThread = new boost::thread(boost::bind(&boost::asio::io_service::run, &m_io_service));
}
void stop()
{
m_listenThread->join();
}
private:
void handleAccept(const boost::system::error_code& error, boost::asio::ip::tcp::acceptor& acceptor)
{
std::cout << "receiverd incomming connection" << std::endl;
if(error)
std::cout << "ERROR: " << error.message() << "(" << error.value() << ")" << std::endl;
}
boost::asio::io_service m_io_service;
boost::asio::ip::tcp::iostream m_stream;
boost::thread* m_listenThread;
};
int main(int argc, char *argv[])
{
Server server;
server.listen(10000);
while(1);
}
Upvotes: 3
Views: 1729
Reputation: 69882
acceptor::async_accept
returns immediately, scheduling a call of the handler when either there is an error or a connection is accepted (1)
the listen() function is returning, which is causing the destruction of the acceptor (2)
When an acceptor
(or socket
, or deadline_timer
) is destroyed, all pending handlers are scheduled on the io_service
with an error code of asio::error::operation_aborted
. This is to satisfy the postconditions of the async_ functions (i.e., "the handler will be called exactly once, as if by io_service.post()") (3)
Therefore, at point (2), your handler is being scheduled - just before the code returns to the main loop.
To fix:
ensure that the acceptor
survives until the handler has been called. This is standard practice in asio async programming. The examples on the boost website will help you to make sense of the (sparse) asio documentation.
Don't lose hope. It took me a long time to learn how to use asio properly, and to realise how fantastically powerful it is.
Upvotes: 3