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

Vla*_*nko 5 c++ windows handler asyncsocket boost-asio

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

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

但socket :: cancel()的文档说明:

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

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

Vla*_*nko 13

好的,答案是:

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

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

  • 已被调用; 要么
  • 已经在不久的将来排队等待调用.

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

我报告的行为实际上很有意义,似乎每个使用Asio的人都知道这一点.我已经梳理了Asio的邮件列表,并在这里,这里,这里这里找到了很多关于这个主题的讨论.

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