gpt4 book ai didi

c++ - asio : is it safe to restart a async_read_some/async_write_some after cancel

转载 作者:搜寻专家 更新时间:2023-10-31 02:16:57 25 4
gpt4 key购买 nike

我很难在文档中找到明确的答案。

我想知道取消异步读取或写入操作然后重新启动操作是否会导致数据流损坏?

详细阅读:如果 async_read_some 操作正在运行:

  • 通过流描述符取消该操作
  • 等待处理程序完成并处理结果(使用 operation_aborted 或传输的字节)。

我能确定当我开始一个新的 async_read_some 操作时,没有数据丢失吗? IE。当处理程序返回 operation_aborted 错误时,没有数据被读取?

同样适用于 async_write_some 操作。当我取消操作时,等待处理程序完成,处理结果(我再次知道返回不需要operation_aborted),然后开始写入剩余数据,流是否可能重复数据? IE。 cancel会不会导致恢复写入时数据重复写入?

最佳答案

cancel() 本身不会导致流中的数据丢失或重复。如果应用程序满足以下条件,数据丢失或重复只会发生在应用程序协议(protocol)中:

  • 使用相同的底层内存启动多个读取操作,这些操作在不处理已读取数据的情况下成功
  • 使用相同的底层内存启动多个写入操作,这些操作在不更改已写入内存内容的情况下成功

正确处理传递给完成处理程序的 error_codebytes_transferred 将防止这种形式的数据丢失或重复。如果 bytes_transferred 大于 0,则数据已从套接字读入缓冲区或从缓冲区写入套接字。请注意,如果某个操作已被调用或在不久的将来排队等待调用,则该操作将不再可取消。考虑以下场景,其中 socket42 字节可供读取:

assert(socket.available() == 42);
std::array<char, 32> buffer;
socket.async_read_some(boost::asio::buffer(buffer), ...); // op 1
socket.cancel();
socket.async_read_some(boost::asio::buffer(buffer), ...); // op 2
io_service.run();

如果 op 1 成功并将 32 字节读入 buffer,则 10 字节仍可用于从 socket 读取。 op 1 的完成处理程序将排队等待将来调用,error_code 为成功,bytes_transferred32。此时,socket.cancel()op 1 没有影响。启动 op 2 后,10 剩余字节准备好进入 buffer,覆盖 op 1 中的一些未处理数据op 2 的完成处理程序将排队等待将来调用,error_code 为成功,bytes_transferred10.


对于非组合操作,例如socket.async_read_some() :

  • 如果发生错误,例如取消,则error_code 不会是boost::system::errc::successbytes_transferred永远是 0
  • 如果没有发生错误,则 error_code 将是 boost::system::errc::successbytes_transferred 将更大小于或等于 0

此行为记录在 StreamSocketService 中的 async_receive()async_send() 函数:

If the operation completes successfully, the [handler] is invoked with the number of bytes transferred. Otherwise it is invoked with 0.

另一方面,使用组合操作,例如 boost::asio::async_read() ,可以使用非成功的 error_code 和非零的 bytes_transferred 调用处理程序。例如,如果启动 async_read() 操作并设置为在完成之前读取 1024 个字节,则它可能会多次调用 async_read_some()。如果收到 256 个字节然后连接关闭,async_read() 处理程序将有一个非零的 error_code 并且 bytes_transferred 将指示缓冲区的 256 个字节是有效的。

关于c++ - asio : is it safe to restart a async_read_some/async_write_some after cancel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36334161/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com