2016-04-30 156 views
0

我有一個簡單的TCP服務器,一個線程與asio循環和一個線程池來執行計算。我能夠聽到連接在主線程中寫入內容。但我不能等待工作線程的回答,因爲連接在被接受後立即關閉。Boost Asio延遲寫入TCP套接字

我嘗試使用截止日期計時器,但由於某種原因,它立即被稱爲「中止操作」錯誤。

整個過程我想實現的是:

  • 接受連接
  • 寫點東西
  • 發送任務給工人池
  • 等待來自工人的答案(我使用線程安全隊列從工作人員池中讀取消息)
  • 將回答寫入套接字
  • 關閉連接

這裏是我的代碼

class tcp_connection 
: public boost::enable_shared_from_this<tcp_connection> 
{ 
    public: 
    typedef boost::shared_ptr<tcp_connection> pointer; 

    static pointer create(boost::asio::io_service& io_service) 
    { 
     return pointer(new tcp_connection(io_service)); 
    } 

    tcp::socket& socket() 
    { 
     return socket_; 
    } 

    void start() 
    { 
     message_ = "Write me in 5 sec"; 
     boost::asio::deadline_timer t(service_, boost::posix_time::seconds(5)); 
     t.async_wait(boost::bind(&tcp_connection::writeAfter, shared_from_this(), boost::asio::placeholders::error)); 
    } 

    private: 
    tcp_connection(boost::asio::io_service& io_service) 
     : service_(io_service), socket_(io_service) 
    { 
    } 

    void writeAfter(const boost::system::error_code&) { 
     std::cout << "writing to socket" << std::endl; 
     boost::asio::async_write(socket_, boost::asio::buffer(message_), 
      boost::bind(&tcp_connection::handle_write, shared_from_this(), 
      boost::asio::placeholders::error, 
      boost::asio::placeholders::bytes_transferred)); 
    } 


    void handle_write(const boost::system::error_code& /*error*/, 
     size_t /*bytes_transferred*/) 
    { 
    } 

    boost::asio::io_service &service_; 
    tcp::socket socket_; 
    std::string message_; 
}; 

編輯:調試日誌

@asio|1462018696.996630|0*1|[email protected]_wait 
@asio|1462018696.996675|0|[email protected] 
@asio|1462018696.996694|0*2|[email protected]_accept 
@asio|1462018696.996714|0*3|[email protected]_wait 
@asio|1462018696.996736|>1|ec=system:125 

正如我們所看到的取消被稱爲計時器,但我沒有在一個單一的取消我的代碼,所以我不知道它爲什麼叫。

非常感謝您的幫助

回答

1

你還在聽其他連接創建tcp_connection後?

既然你還沒有要求你的新連接,io_service.run()爲該線程可能只是完成async_readasync_read_some ...

如果您在tcp_connection構造啓動deadline timer,它應該保持io_service.run()去和發送消息。

+0

是的我在創建'tcp_connection'之後正在監聽其他連接。'012_ 'io_sevice'仍在運行。問題是套接字本身被關閉 –

+0

正如你所建議的,我在構造函數中啓動了計時器(這也意味着計時器在任何傳入連接之前啓動)但是我仍然得到錯誤125.我將調試日誌添加到我的文章 –

0

我找到了原因。

共享指針發生混亂,連接對象被破壞。 TCP對象也是如此。連接很近。

感謝@kenba的幫助!

+1

我很高興我幫你找到了問題的原因。如果您有興趣使用現成的'boost asio' TCP服務器,我在[via-httplib](https://github.com/kenba/via-httplib)上創建了一個作爲HTTP服務器的一部分。 – kenba

+0

太糟糕了我剛剛完成我的實施......如果我只知道:p –