boost :: asio错误“I / O操作已中止...”

时间:2011-01-06 20:27:25

标签: c++ boost-asio

我收到此错误消息

“由于线程退出或应用程序请求,I / O操作已中止”

使用boost :: asio :: socket :: async_read_some()

错误是什么意思?我应该寻找什么?

以下是相关代码:

void tcp_connection::start()
{
  printf("Connected to simulator\n");

  socket_.async_read_some(boost::asio::buffer(myBuffer,256),
      boost::bind(&tcp_connection::read_sim_handler,this,
      boost::asio::placeholders::error,
      boost::asio::placeholders::bytes_transferred));
}

void tcp_connection::read_sim_handler(
                                  const boost::system::error_code& error, // Result of operation.
                                  std::size_t len )         // Number of bytes read.
{
try {
if (error == boost::asio::error::eof) {
    // Connection closed cleanly by peer.
    printf("Sim connection closed\n");
    return;
} else if (error) {
    throw boost::system::system_error(error); // Some other error.  if( ! error ) 
}

socket_.async_read_some(boost::asio::buffer(myBuffer,256),
    boost::bind(&tcp_connection::read_sim_handler,this,
    boost::asio::placeholders::error,
    boost::asio::placeholders::bytes_transferred));
}
 catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
}

当我用start()方法中的read_some()替换对async_read_some()的调用时,一切正常(除了等待消息的服务器块!)

发表评论后,我发现tcp_connection超出了范围。我从http://www.boost.org/doc/libs/1_45_0/doc/html/boost_asio/tutorial/tutdaytime3.html复制了代码  这说: “我们将使用shared_ptr和enable_shared_from_this,因为只要存在引用它的操作,我们希望保持tcp_connection对象保持活动状态。” 我承认我不知道这意味着什么。所以我以某种方式打破了它?

进一步评论后,答案是

void tcp_connection::start()
{
  printf("Connected to simulator\n");

  socket_.async_read_some(boost::asio::buffer(myBuffer,256),
      boost::bind(&tcp_connection::read_sim_handler,
              shared_from_this(),
      boost::asio::placeholders::error,
      boost::asio::placeholders::bytes_transferred));
}

传递shared_from_this()而不是使用由服务器代码建立的聪明(太聪明?)保持活动基础结构,即使连接管理器不在范围内,通过正常方式。有关技术细节,请参阅接受答案下的评论。

1 个答案:

答案 0 :(得分:2)

在异步操作完成之前,您的tcp_connection类或缓冲区对象可能超出范围。

由于您的程序基于其中一个教程示例,为什么不查看另一个读取某些数据的示例:http://www.boost.org/doc/libs/1_45_0/doc/html/boost_asio/example/echo/async_tcp_echo_server.cpp

您的课程超出范围的原因是您不再使用shared_from_this()。这样做是为您的类创建一个由绑定处理程序存储的shared_ptr。这意味着shared_ptr将使您的类保持活动状态,直到调用您的处理程序。

这也是你需要从enable_shared_from_this继承的原因。

超出范围的最后一个shared_ptr将删除您的类实例。