2012-06-15 153 views
2

我想要一個有狀態的通信,但不喜歡boost的echo服務器示例。我的套接字將準備永久閱讀,每當它接收到新數據時,它將調用虛擬方法dataAvailable(string)但是它可以隨時做async_writeboost asio有狀態套接字接口

void connected(const boost::system::error_code &ec) { 
    _socket.async_read_some(boost::asio::buffer(_buffer, max_length), 
     boost::bind(&Session::handler_read, this, boost::asio::placeholders::error, 
     boost::asio::placeholders::bytes_transferred)); 
    //boost::asio::async_read(_socket, boost::asio::buffer(_buffer, max_length), 
    // boost::bind(&Session::handler_read, this, boost::asio::placeholders::error, 
    // boost::asio::placeholders::bytes_transferred)); 
    std::cout << ">> Session::connected()" << std::endl; 
} 

void handler_read(const boost::system::error_code &ec, size_t bytes_transferred) { 
    if(ec) { 
    std::cout << ec.message() << std::endl; 
    } else { 
    //std::copy(_buffer, _buffer+bytes_transferred, data.begin()); 
    std::string data(_buffer, _buffer+bytes_transferred); 
    std::cout << ">> Session[ " << id() << "]" << "::handler_read(): " << 
      bytes_transferred << " " << data << std::endl; 
    boost::asio::async_write(_socket, boost::asio::buffer(_buffer, max_length), 
      boost::bind(&Session::handler_write, this, 
      boost::asio::placeholders::error)); 
    _socket.async_read_some(boost::asio::buffer(_buffer, max_length), 
      boost::bind(&Session::handler_read, this, boost::asio::placeholders::error, 
      boost::asio::placeholders::bytes_transferred)); 
    //boost::asio::async_read(_socket, boost::asio::buffer(_buffer, max_length), 
     // boost::bind(&Session::handler_read, this, 
     // boost::asio::placeholders::error, 
     // boost::asio::placeholders::bytes_transferred)); 
     //call dataAvailable(_buffer); 
    } 
} 

void handler_write(const boost::system::error_code &ec) { 
    if(ec) { 
    std::cout << ec.message() << std::endl; 
    } else { 
    _socket.async_read_some(boost::asio::buffer(_buffer, max_length), 
      boost::bind(&Session::handler_read, this, boost::asio::placeholders::error, 
      boost::asio::placeholders::bytes_transferred)); 
    //boost::asio::async_read(_socket, boost::asio::buffer(_buffer, max_length), 
     // boost::bind(&Session::handler_read, this, 
     // boost::asio::placeholders::error, 
     // boost::asio::placeholders::bytes_transferred)); 
    } 
} 
  1. 這是實現好?因爲多個線程可能會執行讀取和寫入操作。其中寫操作是在矩陣
  2. 爲什麼它不工作(不Echo的接收到的字符串)某些細胞的更新用,當我使用的async_read代替async_read_some
  3. 在我的聽力服務器,我無處調用listen方法。但仍然在工作。那麼爲什麼有一種聽法?以及何時使用?
  4. 我想從客戶端退出客戶端套接字時收到通知。例如客戶已關閉連接。我該怎麼做 ?我的方式是讀 read_handler但這是唯一的方法嗎?
  5. 我有一個Session類,每個會話都有一個套接字。我在會話管理器中存儲Session*集合。現在當我關閉一個套接字並delete它會話變爲空。它可能發生在vector的中間。那麼如何安全地刪除那個會話?
+0

你可以用[self contained reproduction](http://sscce.org/)來編輯你的問題,這樣我們就可以看到它不起作用了嗎?在你發佈的代碼片段中沒有明顯的錯誤。 –

回答

0

你的代碼有一個嚴重的問題。想象一下,你有不對稱的網絡鏈接,並且能夠比發送更快地接收。

  1. 接收消息
  2. 待辦事項ASYNC_WRITE(但需要時間)
  3. 計劃未來閱讀
  4. 收到一條消息
  5. 做第二ASYNC_WRITE(第一個是還沒有完成,你會得到垃圾一個鏈接的另一端)
  6. 安排下一個閱讀
  7. 第一個async_write完成並計劃一個async_read_some

總之,你要求asio一次完成多個讀寫操作。

爲什麼它不工作(不Echo的接收到的字符串)當我使用的async_read_some

你發送足夠的數據(max_length)async_read呢?也許你想使用boost::asio::transfer_at_least(min_length)

在我的偵聽服務器中,我無處調用listen方法。但仍然在工作。那麼爲什麼有一種聽法?以及何時使用?

您可能在某處創建acceptor對象。

我想從客戶端退出客戶端套接字時收到通知。例如客戶已關閉連接。我該怎麼做 ?我出來的方式是通過閱讀read_handler中的文件結束但是唯一的方式?

您可以創建包裝,這將採取EOF並做一些清理。然後用wrapper封裝所有的自定義處理程序,並將其作爲處理函數傳遞給:: asio。如果你願意,這樣你只有一個地方可以處理EOF錯誤。

我有一個Session類,每個會話都有一個套接字。我正在會話管理器中存儲Session *集合。現在當我關閉套接字並刪除它時,會話變爲空。它可能發生在矢量的中間。那麼如何安全地刪除那個空會話?

使用boost::shared_ptr在處理程序等,並boost::shared_ptrboost::weak_ptr在會話管理器的矢量。

相關問題