我很难在文档中找到明确的答案。
我想知道是否取消异步读取或写入操作,然后重新启动操作会导致数据流损坏?
详细阅读:如果正在运行async_read_some操作:
我可以确定当我开始新的async_read_some操作时,没有数据丢失吗?即当处理程序返回operation_aborted错误时,没有读取数据?
同样适用于async_write_some操作。当我取消操作时,等待处理程序完成,处理结果(再次我知道返回不需要是operation_aborted),然后开始写剩余数据,流是否有可能重复数据?即可以取消导致在恢复写入时双倍写入数据吗?
答案 0 :(得分:2)
本身cancel()
不会导致流中的数据丢失或重复。如果应用程序:
正确处理传递给完成处理程序的error_code
和bytes_transferred
可以防止这种形式的数据丢失或重复。如果bytes_transferred
大于0
,则数据已从套接字读入缓冲区或从缓冲区写入套接字。请注意,如果某个操作已在不久的将来被调用或排队等待调用,则该操作不再可取消。请考虑以下情况:socket
可以读取42
个字节:
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_transferred
32
。此时,socket.cancel()
对op 1
没有影响。在启动op 2
后,10
剩余的buffer
字节就会准备好进入op 1
,从op 2
覆盖一些未处理的数据。 error_code
的完成处理程序将在以后成功排队,bytes_transferred
成功10
error_code
。
对于非组合操作,例如socket.async_read_some()
:
boost::system::errc::success
将不会是bytes_transferred
而0
将始终为error_code
boost::system::errc::success
将bytes_transferred
且0
将大于或等于async_receive()
StreamSocketService async_send()
和0
函数记录了此行为:
如果操作成功完成,则调用[handler]并传输字节数。否则,使用
error_code
调用它。
另一方面,对于组合操作,例如boost::asio::async_read()
,可以使用非成功bytes_transferred
和非零async_read()
来调用处理程序。例如,如果启动async_read_some()
操作并在完成之前将其设置为读取1024个字节,则可以多次调用async_read()
。如果接收到256个字节然后关闭连接,则error_code
处理程序将具有非零bytes_transferred
,{{1}}将指示缓冲区的256个字节有效。