Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

boost::asio server - detect failure to listen to server port

I have a boost::asio based server which works fine, except that I'm trying to add a check that nothing else is accepting connections on the same port. If I create two of the servers, one of them consistently accepts the connections, but the other does not report any error ( which of the two accepts all connections appears to be random ).

The relevant bits of the server class ( it's a template which uses a base class which has Accepted() and typedefs for the connection type to create ) are:

        MessageServer ( boost::asio::io_service &io, unsigned short port_num )
            : BaseServerType ( io ), acceptor_ ( io, boost::asio::ip::tcp::endpoint ( boost::asio::ip::tcp::v4(), port_num ) ) {
            Listen();
        }
        void Listen () {
            boost::system::error_code ec;
            acceptor_.listen ( boost::asio::socket_base::max_connections, ec );

            if ( !ec ) {
                start_accept();
            } else {
                // not reached even if a separate process 
                // is already listening to that port
                connection_pointer new_connection;
                BaseServerType::Accepted ( new_connection );
            }
        }

    private:
        void start_accept() {
            connection_pointer new_connection ( CreateConnection ( acceptor_.io_service() ) );

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

        void handle_accept ( connection_pointer new_connection, const boost::system::error_code &error ) {
            if ( !error ) {
                BaseServerType::Accepted ( new_connection );
                new_connection -> Start();
                start_accept();
            } else {
                // never reached
                new_connection.reset();
                BaseServerType::Accepted ( new_connection );
            }
        }

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

acceptor.listen() doesn't throw either.

How is a failure to listen to a server port reported in boost::asio?

like image 475
Pete Kirkham Avatar asked Feb 15 '11 10:02

Pete Kirkham


1 Answers

boost::asio::ip::tcp::acceptor constructor you use has a default argument reuse_address = true. this sets SO_REUSEADDR socket option. disabling this option you'll receive error on acceptor.listen(). more info about SO_REUSEADDR here

Be aware that this option is treated differently on windows and linux

like image 121
Andriy Tylychko Avatar answered Nov 07 '22 08:11

Andriy Tylychko