2013-04-12 49 views
1

在線67我有這應該每當服務器會話類,但由於某種原因,功能沒有被調用接收到數據包,以輪詢的代碼C++:BOOST-ASIO read_handler()不能按預期工作?

void session::read_handler(const boost::system::error_code& ec, std::size_t bytes_transferred) 
{ 
     std::cout<<bytes_transferred<<std::endl; 
} 

io_service.run();read_handler()int main()中被調用。該代碼基本上是Boost站點上異步服務器的示例,其中添加了我的功能。繼承人的代碼。

#include <cstdlib> 
#include <iostream> 
#include <boost/bind.hpp> 
#include <boost/asio.hpp> 

using boost::asio::ip::tcp; 

class session 
{ 
public: 
    session(boost::asio::io_service& io_service) 
    : socket_(io_service) 
    { 
    } 

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

    void start() 
    { 
    socket_.async_read_some(boost::asio::buffer(data_, max_length), 
     boost::bind(&session::handle_read, this, 
      boost::asio::placeholders::error, 
      boost::asio::placeholders::bytes_transferred)); 
    } 
void read_handler(const boost::system::error_code& ec, std::size_t bytes_transferred); 


private: 
    void handle_read(const boost::system::error_code& error, 
     size_t bytes_transferred) 
    { 
    if (!error) 
    { 
     boost::asio::async_write(socket_, 
      boost::asio::buffer(data_, bytes_transferred), 
      boost::bind(&session::handle_write, this, 
      boost::asio::placeholders::error)); 
    } 
    else 
    { 
     delete this; 
    } 
    } 

    void handle_write(const boost::system::error_code& error) 
    { 
    if (!error) 
    { 
     socket_.async_read_some(boost::asio::buffer(data_, max_length), 
      boost::bind(&session::handle_read, this, 
      boost::asio::placeholders::error, 
      boost::asio::placeholders::bytes_transferred)); 
    } 
    else 
    { 
     delete this; 
    } 
    } 

    tcp::socket socket_; 
    enum { max_length = 1024 }; 
    char data_[max_length]; 
}; 
void session::read_handler(const boost::system::error_code& ec, std::size_t bytes_transferred) 
{ 
     std::cout<<bytes_transferred<<std::endl; 
} 

class server 
{ 
public: 
    server(boost::asio::io_service& io_service, short port) 
    : io_service_(io_service), 
     acceptor_(io_service, tcp::endpoint(tcp::v4(), port)) 
    { 
    start_accept(); 
    } 


private: 
    void start_accept() 
    { 
    session* new_session = new session(io_service_); 
    acceptor_.async_accept(new_session->socket(), 
     boost::bind(&server::handle_accept, this, new_session, 
      boost::asio::placeholders::error)); 
    } 

    void handle_accept(session* new_session, 
     const boost::system::error_code& error) 
    { 
    if (!error) 
    { 
     new_session->start(); 
    } 
    else 
    { 
     delete new_session; 
    } 

    start_accept(); 
    } 

    boost::asio::io_service& io_service_; 
    tcp::acceptor acceptor_; 
}; 

int main() 
{ 
    try 
    { 
    boost::asio::io_service io_service; 
    server s(io_service, 4000); 

    io_service.run(); 
    } 
    catch (std::exception& e) 
    { 
    std::cerr << "Exception: " << e.what() << "\n"; 
    } 

    return 0; 
} 

回答

1

會議:: read_handler(...)沒有設置爲處理程序。

handle_accept()被調用,因爲它被設置爲處理程序:

acceptor_.async_accept(new_session->socket(), 
     boost::bind(&server::handle_accept, this, new_session, 
      boost::asio::placeholders::error)); 

handle_read(...)被調用bacause它被設置爲處理程序:

socket_.async_read_some(boost::asio::buffer(data_, max_length), 
      boost::bind(&session::handle_read, this, 
      boost::asio::placeholders::error, 
      boost::asio::placeholders::bytes_transferred)); 

同爲handle_write(。 ..) - 通過handle_read函數設置。

但是read_handler沒有設置。改用handle_read。或者從handle_read調用read_handler。

void handle_read(const boost::system::error_code& error, 
     size_t bytes_transferred) 
    { 
    if (!error) 
    { 
     std::cout<<bytes_transferred<<std::endl; // try this. 
     read_handler(error, bytes_transferred); // OR this. 

     boost::asio::async_write(socket_, 
      boost::asio::buffer(data_, bytes_transferred), 
      boost::bind(&session::handle_write, this, 
      boost::asio::placeholders::error)); 
    } 
    else 
    { 
     delete this; 
    } 
    } 
1

這個函數會得到從來沒有所謂,因爲你沒有把它也沒有把它作爲一個處理程序的異步功能之一。

您可以將處理程序看作狀態機的狀態,並將async_ *調用看作這些狀態之間的轉換。你的狀態有(起點爲start_accept,從server::server稱爲:

<<start>>     --async_accept-----> <server::handle_accept> //via server::server > server::start_accept 
<server::handle_accept>  --async_read_some--> <session::handle_read> //via session::start 
<session::handle_read>  --async_write------> <session::handle_write> 
<session::handle_write>  --async_read_some--> <session::handle_read> 

的路徑是隻對案件沒有錯誤錯誤情況是微不足道的,他們剛剛結束程序,或者在handle_accept情況下,只需重試。你可以看到handle_readhandle_write,但read_handler之間的可能循環不息的轉變。

不是比賽的一部分。