2011-02-15 10 views
7

Tengo un impulso :: servidor basado asio que funciona muy bien, excepto que estoy tratando de añadir un cheque que nada más está aceptando conexiones en el mismo puerto. Si creo dos de los servidores, uno de ellos acepta consistentemente las conexiones, pero el otro no informa ningún error (cuál de los dos acepta que todas las conexiones parecen ser al azar).impulso :: asio del servidor - detectar la falta de escucha a puerto del servidor

Los bits correspondientes de la clase servidor (Es una plantilla que utiliza una clase base que haya aceptado() y typedefs para el tipo de conexión para crear) son:

 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 arrojar tampoco.

¿Cómo se informa una falla al escuchar un puerto del servidor en boost :: asio?

Respuesta

9

boost::asio::ip::tcp::acceptor constructor que utiliza tiene un argumento predeterminado reuse_address = true. esto establece la opción de socket SO_REUSEADDR. deshabilitando esta opción recibirás un error en acceptor.listen(). more info about SO_REUSEADDR here

Tenga en cuenta que esta opción es treated differently on windows and linux

+0

Si traduzco la descripción anterior, aquí está el código. 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, false)) { Escuchar(); } ... try { servidor = new MessageServer (io_service_, 5000); } catch (const std :: excepción y ex) { printf ("Error de aprieto:% s \ n", ex.what()); } – Hill

0

El error que desea sería thrown or returned de boost::asio::ip::tcp::acceptor::bind(). El constructor que está utilizando exhibirá este mismo comportamiento, le sugiero que reduzca su ejemplo a algo más pequeño que sea reproducible. No es obvio para mí cómo manejas las excepciones lanzadas desde tu MessageServer ctor.

+0

Al igual que con cualquier constructor que pueda arrojar, cualquier cosa que crea los servidores o bien envuelve el constructor en try/catch si es recuperable, o deja que se filtre al alcance externo si no lo es. –