2011-02-15 103 views
7

我有一個基於boost :: asio的服務器工作正常,除了我試圖添加一個檢查,沒有別的是在同一端口上接受連接。如果我創建了兩個服務器,其中一個服務器始終接受連接,但另一個不報告任何錯誤(兩個接受所有連接中的哪一個似乎是隨機的)。boost :: asio服務器 - 檢測服務器端口失敗

服務器類的相關位(這是它使用),其已接受(基類和類型定義用於連接類型的創建模板)是:

 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()沒有按」也不扔。

如何收聽boost :: asio中報告的服務器端口失敗?

回答

9

boost::asio::ip::tcp::acceptor您使用的構造函數具有默認參數reuse_address = true。這設置SO_REUSEADDR套接字選項。禁用此選項,您將收到acceptor.listen()上的錯誤。 more info about SO_REUSEADDR here

注意,這個選項是treated differently on windows and linux

+0

如果我翻譯上面的描述,這裏是代碼。 (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)){ Listen(); } ... try { server = new MessageServer(io_service_,5000); (「綁定錯誤:%s \ n」,ex.what());}}; catch(std :: exception const&ex) { } } – Hill 2015-11-09 08:16:32

0

你想會是從boost::asio::ip::tcp::acceptor::bind()thrown or returned錯誤。你正在使用的constructor將展示這種相同的行爲,我建議你把你的例子放在可重現的小的東西上。我不清楚你如何處理從你的MessageServer ctor拋出的異常。

+0

與任何可以拋出的構造函數一樣,無論創建哪個服務器,都會將構造函數包裝在try/catch中,如果它是可恢復的,或者讓它滲透到外部範圍(如果不是)。 – 2011-02-15 16:57:11