2013-02-07 48 views
1

我有一臺服務器,使用asio和下面的代碼,從示例中100%複製。沒有連接時,代碼表現良好。但是,只要第一個客戶端連接,句柄接受就會開始輸出大量的系統:9錯誤,我無法連接任何其他客戶端。連接的單個客戶端可以很好地執行異步讀/寫操作。我不知道自己做錯了什麼。我已經在線程池中嘗試了使用和不使用io_service的代碼,並得到了相同的結果。boost :: asio無限循環系統:第一次連接後出現9錯誤

Server::Server(io_service& io_service, 
     const std::string address, 
     const std::string port) 
    : io_service_(io_service), 
    //zmq_strand_(io_service), 
     acceptor_(io_service) { 

    ip::tcp::resolver resolver(io_service_); 
    ip::tcp::resolver::query query(address, port); 
    ip::tcp::endpoint endpoint = *resolver.resolve(query); 
    acceptor_.open(endpoint.protocol()); 
    acceptor_.set_option(ip::tcp::acceptor::reuse_address(true)); 
    acceptor_.bind(endpoint); 
    acceptor_.listen(); 
    start_accept(); 
    } 

void Server::start_accept() { 
    auto session = std::shared_ptr<Session>(new Session(io_service_,session_manager_)); 

    acceptor_.async_accept(session->socket() 
     ,std::bind(&Server::handle_accept,this,session,std::placeholders::_1)); 
} 

void Server::handle_accept(std::shared_ptr<Session> session, const system::error_code& error) { 
    if (!error) { 
    std::cout << "handle_accept" << std::endl; 
    session->start(); 
    } else { 
     std::cout << error << std::endl; 
    } 
    start_accept(); 
} 

小更新: 而不是使用我用丹尼斯提出了例如http3例子。它不太複雜,並使服務器的行爲正確。我還沒有找到一個合理的解釋,爲什麼前面的代碼不起作用。這確實:

Server::Server(
     io_service &service, 
     const uint8_t num_threads, 
     const std::string address, 
     const uint16_t port) 
    : 
     num_threads_(num_threads), 
    //zmq_strand_(io_service), 
     acceptor_(service,ip::tcp::endpoint(ip::tcp::v4(),port)) { 

    //io_service::work work(io_service_); 
    start_accept(); 
    } 


void Server::start_accept() { 
    auto session = std::shared_ptr<Session>(new Session(acceptor_.get_io_service(),session_manager_)); 

    acceptor_.async_accept(session->socket() 
     ,std::bind(&Server::handle_accept,this,session,std::placeholders::_1)); 
} 

void Server::handle_accept(std::shared_ptr<Session> session, const system::error_code& error) { 
    if (!error) { 
    std::cout << "handle_accept" << std::endl; 
    session->start(); 
    } 
    start_accept(); 
} 

void Server::start() { 
    std::set<std::unique_ptr<std::thread>> threads; 

    for(unsigned int i = 0; i < num_threads_; ++i) { 
     threads.insert(std::unique_ptr<std::thread>(new std::thread([&]() { 
      acceptor_.get_io_service().run(); 
      }) 
     )); 
    } 
    std::cout << threads.size() << " threads started" << std::endl; 
    for(auto &t:threads) { 
     t->join(); 
    } 
    std::cout << threads.size() << " threads joined" << std::endl; 
} 
+2

這個教程看起來準確而教程比較你的代碼:http://www.boost.org/doc/ libs/1_53_0/doc/html/boost_asio/tutorial/tutdaytime7/src.html –

+0

服務器對象是否超出範圍?它的一生如何管理? –

+0

據我所知,它並沒有超出範圍。它在main()中被調用,我在其中創建io_service的一個實例,創建一個Server實例,然後啓動一個調用io_service.run()的線程池。我試着用池和直接調用io_service.run()沒有區別。線程池連接並在連接後輸出跟蹤 - 該跟蹤從不輸出。 – mna

回答