2013-04-12 22 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之间的可能循环不息的转变。

不是比赛的一部分。