取消后调用boost :: asio异步处理程序而没有错误

时间:2012-05-23 11:00:32

标签: c++ windows handler boost-asio asyncsocket

我的代码在单个线程中使用boost :: asio和io_service来执行各种套接字操作。所有操作都是异步的,每个处理程序都依赖于boost::system::error_code(特别是boost::asio::error::operation_aborted)来确定操作的结果。

在我改变逻辑以创建几个并发连接并选择最快的连接之​​前,它一直运行良好。也就是说,当第一个async_read_some处理程序触发时,我取消其他套接字(关闭,关闭 - 所有内容)并继续当前的套接字。在95%的情况下,使用operation_aborted错误调用其他套接字的读取处理程序。但有时,这些读取处理程序被调用而没有错误,告诉我它们已经成功接收了N个字节。

但是socket :: cancel()states的文档:

  

此函数会导致所有未完成的异步连接,发送和   接收立即完成的操作,以及处理程序   取消的操作将传递boost::asio::error::operation_aborted错误。

所以,问题:我真的可以依赖生产代码中的operation_aborted错误吗?如果可以的话,它是来自增强1.46.1的Asio中的一个错误吗?如果我不能,是否有关于此的官方文件?

2 个答案:

答案 0 :(得分:12)

好的,答案是:

  1. 不,我不能仅仅依赖operation_aborted错误。
  2. 当然,这不是Asio的错误,只是缺乏经验。
  3. 有一点官方documentation。它适用于计时器,而不是插座,但适用相同的原则:

  4. 如果在调用cancel()时定时器已经过期,那么异步等待操作的处理程序将:

    • 已被调用;或
    • 已在不久的将来排队等候。

    基本上,我假设如果我为io_service使用单个线程,那么在执行某些处理程序时将阻止每个操作。

    我报告的行为实际上很有意义,似乎每个使用Asio的人都知道这一点。我已经梳理了Asio的邮件列表,并就主题herehereherehere进行了大量讨论。

      

    例如,写操作可能会成功完成   你是在处理程序内,但在你开始打电话之前   套接字取消,导致其完成处理程序被发布到队列中。   据我了解,错误代码由状态决定   完成的操作,而不是当时套接字的状态   处理程序从队列中删除并执行。

答案 1 :(得分:2)

考虑同时建立两个连接。两个处理程序都将触发,一个将首先处理,第二个处于队列中(或在另一个线程上处理)。人们可以想到更多这样的例子。

因此,为了实现您的要求,您需要更多的逻辑。