2013-07-12 37 views
0

我在我的應用程序的代碼片段,我目前正在寫:越來越怪異的錯誤,而使用Boost.Asio的的免費async_ *功能

#include "ClientSession.hpp" 
void ClientSession::start(void) 
{ 
    auto Self(shared_from_this()); 

    //boost::asio::read(this->_Socket, boost::asio::buffer(this->_ReadBuffer)); 

    //this->_Socket.get_io_service().post(boost::bind(&ClientSession::on_read, shared_from_this(), boost::system::error_code::error_code(), 0)); 

    boost::asio::async_read(this->_Socket, boost::asio::buffer(this->_ReadBuffer), boost::bind(&ClientSession::on_read, Self, _1, _2)); 
} 

void ClientSession::on_read(const boost::system::error_code& Err_, size_t Bytes_) 
{ 
    try 
    { 
     if(Err_) 
     { 
      if(!(Err_ == boost::asio::error::eof || Err_ == boost::asio::error::connection_aborted)) 
      { 
       throw std::runtime_error(Err_.message()); 
      } 
      return; 
     } 

    } 
    catch(std::exception& Ex_) 
    { 
     this->_OutputHandler.write_error(Ex_.what()); 
    } 
} 

調用的ClientSession代碼::開始是:

void Application::start_accept() 
{ 

    using namespace boost::asio; 
    ip::tcp::endpoint Endpoint(ip::address::from_string(this->_Config.get_client_login_server().first), this->_Config.get_client_login_server().second); 
    this->_ClientAcceptor.open(Endpoint.protocol()); 
    this->_ClientAcceptor.bind(Endpoint); 
    this->_ClientAcceptor.listen(); 

    std::shared_ptr<ClientSession> Session = ClientSession::create_new(this->_AsioService, this->_OutputHandler); 
    this->_ClientAcceptor.async_accept(Session->get_socket(), boost::bind(&Application::handle_accept, shared_from_this(), Session, _1)); 

} 

如果我運行的應用程序與註釋掉的行之一,它工作得很好(在boost :: asio :: read版本從客戶端傳輸的消息被寫入到讀取緩衝區和在後期版本處理函數被調用時沒有任何問題),但是如果嘗試使用我的應用程序!lication與async_read部分我的整個應用老是死機,不調用完整的手柄,甚至讀取字節!至少它看起來像從輸出ASIO給我:

@asio | 1373633560.834957 |0*1|[email protected]_accept @asio | 1373633573.324144 |> 1 | EX =系統:0 @asio | 1373633573.324144 | 1 * 2 | [email protected]_receive

我它debbuged到名爲「select_reactor.ipp」的文件,其中應用程序嘗試獲取boost :: asio :: detail :: mutex :: scoped_lock,並且它看起來像是在那裏失敗,會話的完整代碼HOD是:

void select_reactor::start_op(int op_type, socket_type descriptor, 
select_reactor::per_descriptor_data&, reactor_op* op, 
bool is_continuation, bool) 
{ 
    boost::asio::detail::mutex::scoped_lock lock(mutex_); 

    if (shutdown_) 
    { 
    post_immediate_completion(op, is_continuation); 
    return; 
    } 

    bool first = op_queue_[op_type].enqueue_operation(descriptor, op); 
    io_service_.work_started(); 
    if (first) 
    interrupter_.interrupt(); 
} 

我不知道,也許我做一些可怕的錯誤,但我不知道我希望什麼,有人可以給我一個提示,我能做些什麼來解決這個錯誤。

基於我走到這一步的意見,我會添加更完整的代碼片段: 我io_service對象是我的應用類中:

class Application 
    : public std::enable_shared_from_this<Application> 
{ 
typedef boost::asio::io_service Service; 
typedef boost::asio::ip::tcp::acceptor Acceptor; 

public: 
    Application(void) 
     : _ClientAcceptor(_AsioService), _ApplicationRunning(true) 
    { 
    } 

    ~Application(void); 

    /* 
    * This is the main method which starts the actual program routine 
    * called in main() 
    */ 
    int run(void); 

private: 
    /* 
    * Invokes the first accept and then invokes via async. handle_accept, which invokes itself repeatedly 
    */ 
    void start_accept(void); 
    /* 
    * handle_accept calls NewClient_->start to invoke the communication with this client 
    */ 
    void handle_accept(std::shared_ptr<ClientSession> NewClient_, const boost::system::error_code& Err_); 

    void loop_for_user_input(void); 
    bool handle_user_input(const std::string& Msg_); 

    /* 
    * This method invokes the threads that call io_service::run() 
    */ 
    static void start_service(Service& AsioService_) { try { AsioService_.run(); } catch(const std::exception& Ex_) { std::cout << Ex_.what() << std::endl; } } 

private: 
    Configuration _Config; 
    Service _AsioService; 
    Acceptor _ClientAcceptor; 
    OutputHandler _OutputHandler; 

    bool _ApplicationRunning; 
}; 

和運行方法:

int Application::run(void) 
{ 
    try 
    { 
     this->_Config.load(); 
     this->_OutputHandler.open(this->_Config.get_logs()); 

     this->start_accept(); 

     for(int i = 0; i < 4; i++) 
     { 
      std::thread t(start_service, std::ref(this->_AsioService)); 
      t.detach(); 
     } 

     this->loop_for_user_input(); 

    } 
    catch(const std::runtime_error& Ex_) 
    { 
     this->_OutputHandler.write_error(Ex_.what()); 
    } 

    return 0; 
} 
+0

你試過在valgrind下運行嗎? – sehe

+0

你的io_service在哪裏?有多少個線程正在調用run()?我猜你會遇到一個對象生命期問題,根據你包含的有限代碼很難說。 –

+0

我在帖子中添加了更多完整的代碼來源。我沒有嘗試在valgrind下運行它,因爲我目前正在windows下開發這個應用程序 – Xardaska

回答

1

我發現了錯誤,這只是我的_WIN32_WINNT預處理器指令設置中的一個錯字,它對_WIN32_WINNT 0x0601(對於Windows 7)解決了這個問題。