【问题标题】:Boost.Asio: Operation Cancelled on async_readBoost.Asio:在 async_read 上取消操作
【发布时间】:2011-04-24 18:32:39
【问题描述】:

我与 Boost.Asio 的持续传奇中的另一个...

我有一个简单的异步客户端和服务器,它们利用 async_write 和 async_read 进行通信。客户端可以成功地将字节写入套接字,但服务器永远不会看到它们;我在服务器上的读取处理程序失败并显示“操作已取消”。

我倾向于认为这可能是客户端写入数据的时间问题服务器尝试读取它并失败,但我原以为数据会等待无论如何都在套接字上(除非在此期间套接字已关闭)。

为了测试这一点,我只是在错误处理程序中重新运行了读取操作,即

read_handler()
{
    if (!error) {
        /* bytes read */
    } else {
        async_read(socket, buffer, read_handler)
    }
}

但这一切都让我在pthread_mutex_lock 中通过调用async_receive 出现段错误。

谁能给我指出任何相关信息的方向(或者,更好的是,告诉我我做错了什么;))?

更新:服务器和客户端基于 Asio 文档中的聊天服务器示例,客户端和服务器都在同一进程下运行(这可能是个问题吗?多想一下他们都使用相同的 io_service...);异步和使用 Boost 1.44.0。我正在使用 OS X,但这也可以在 Linux 上重现。

更新 II:我的预感是正确的,如果为服务器和客户端提供了单独的 io_service 对象,那么 async_read 会看到套接字上的字节。这仍然会在boost::asio::detail::kqueue_reactor::post_immediate_completion 中产生一个似乎源于io_service.run() 的段错误。在我继续之前,使用单独的 io_service 对象是正确的方法吗?

【问题讨论】:

  • 你在哪个平台上运行?
  • 平台为OSX和Linux;两者都表现出相同的问题。
  • 我认为我们需要更多地查看您的代码,以便有机会猜测您做错了什么!了解有关您的设置的一些信息也会有所帮助——例如,客户端和服务器是在同一台机器上还是在不同的机器上运行?都是用 boost::asio 写的吗?您使用的是哪个版本的 Boost(asio 最近发生了很大变化)?
  • 我需要一些时间来审查代码,以一个说明问题的小例子;但与此同时,在回答您的其他问题时,这是 boost 1.44.0,客户端和服务器都从同一进程运行,并且都与 Asio 中提供的聊天服务器示例具有显着相似性:) 我将更新原始问题有这些细节。
  • asio 聊天example 没有客户端和服务器在同一个进程中运行。你想通过这样做来完成什么?您需要发布更多代码以供我们帮助。

标签: sockets boost boost-asio


【解决方案1】:

当套接字为closed 或取消时发送操作取消(操作中止错误代码)。

您的连接很可能超出范围。

也许就像我发生的那样,您忘记将 async_handlers 附加到 shared_from_this() 指针。 IE。你应该像这样附加你的处理程序:

async_read(m_socket,
           boost::asio::buffer((void*)m_buffer, m_header_size),
           boost::bind(&TcpConnection::handleRead, 
           shared_from_this(),
           boost::asio::placeholders::error,
           boost::asio::placeholders::bytes_transferred));

是这样的:

async_read(m_socket,
           boost::asio::buffer((void*)m_buffer, m_header_size),
           boost::bind(&TcpConnection::handleRead, 
           this, //<- This will go out of scope and the socket will be closed
           boost::asio::placeholders::error,
           boost::asio::placeholders::bytes_transferred));

【讨论】:

  • 谢谢,我在完全不同的区域发生了崩溃,但也出现了Operation canceled 错误消息。就是this 超出了范围!谢天谢地,我在调试了几个小时后找到了你的答案……
  • 这是所有问题中最好的答案。完全奇怪的错误。诊断绝对准确。
  • 当它通过时,为什么连接会超出范围?
  • this(一个 TcpConnection)因为超出范围而被销毁。几年前我遇到过这个问题,但如果我没记错的话,整个设计都是围绕事件处理程序循环异步的。一个常见的策略是最小化堆使用,因此连接也在堆栈中创建。从函数返回时,调用了析构函数,以便销毁 m_socket 并关闭它。这就是在我们的案例中连接超出范围的原因。我对您@bryanph 的唯一建议是检查您的连接的生命周期,因为这可能是最简单的原因。
  • 谢谢!我发现这个官方的 boost asio 示例似乎教错了,这完全令人不安:boost.org/doc/libs/1_43_0/doc/html/boost_asio/example/http/…
猜你喜欢
  • 2022-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-02
  • 1970-01-01
相关资源
最近更新 更多