gpt4 book ai didi

async_receive 和 async_send 处理程序中的 C++ Boost.Asio 错误

转载 作者:搜寻专家 更新时间:2023-10-31 00:36:47 35 4
gpt4 key购买 nike

  1. 当 error_code 不为 0 时,连接是否正式“失效”?

  2. 当 error_code 不为 0 时,读取处理程序的 bytesReceived 参数是否可能为 0 以外的任何值?如果可能,是否应该处理这些字节?

最佳答案

简而言之,一个不成功的error_code并不能保证连接是死的,对于非组合操作,比如async_receive()bytes_transferred 成功时将为 0 或更多,如果发生错误则始终为 0


不成功的 error_code 并不正式表示连接正式失效。例如,TCP 连接在以下情况下仍然存在:

  • 杰出basic_stream_socket::async_receive()通过 cancel() 取消操作将导致调用处理程序时出现 boost::asio::error::operation_aborted 错误。
  • 全双工连接中只有一部分是shutdown() .例如,如果套接字的接收端关闭,则数据仍然可以通过套接字通过连接发送。

对于非组合操作,当发生错误时,bytes_transferred 将为0。但是,0 并不表示发生了错误。例如,bytes_transferred可以是0error_code可以在使用reactor-style operations时表示成功或者当提供空缓冲区时。 StreamSocketServiceasync_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 个字节是有效的。


这是一个完整的例子demonstrating即使某些操作失败,连接仍然存在:

#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>

void noop() {}

void print_status(
const boost::system::error_code& error,
std::size_t bytes_transferred)
{
std::cout << "error = (" << error << ") " << error.message() << "; "
"bytes_transferred = " << bytes_transferred
<< std::endl;
}

void run_io_service(std::string message, boost::asio::io_service& io_service)
{
std::cout << message << ": ";
io_service.run();
io_service.reset();
}

int main()
{
using boost::asio::ip::tcp;

// Create all I/O objects.
boost::asio::io_service io_service;
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 0));
tcp::socket socket1(io_service);
tcp::socket socket2(io_service);

// Connect the sockets.
acceptor.async_accept(socket1, boost::bind(&noop));
socket2.async_connect(acceptor.local_endpoint(), boost::bind(&noop));
io_service.run();
io_service.reset();

const char data[] = "hello\n";
char buffer[128];

// Create an async receive operation and cancel it.
socket1.async_receive(boost::asio::buffer(buffer), &print_status);
socket1.cancel();
run_io_service("async_receive1", io_service);

// Create an async write operation.
socket1.async_send(boost::asio::buffer(data), &print_status);
run_io_service("async_send1", io_service);

// Shutdown the receive side of the socket then create an async
// receive operation.
socket1.shutdown(tcp::socket::shutdown_receive);
socket1.async_receive(boost::asio::buffer(buffer), &print_status);
run_io_service("async_receive2", io_service);

// Create an async write operation.
socket1.async_send(boost::asio::buffer(data), &print_status);
run_io_service("async_send2", io_service);
}

输出:

async_receive1: error = (system:125) Operation canceled; bytes_transferred = 0
async_send1: error = (system:0) Success; bytes_transferred = 7
async_receive2: error = (asio.misc:2) End of file; bytes_transferred = 0
async_send2: error = (system:0) Success; bytes_transferred = 7

关于async_receive 和 async_send 处理程序中的 C++ Boost.Asio 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20929312/

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