C++Boost.Asio错误在async_receive和async_send处理程序中
C++ Boost.Asio errors in async_receive and async_send handlers
-
当error_code不为0时,连接是否正式"死"?
-
当error_code不为0时,读取处理程序的bytesReceived参数是否可能为0以外的任何值?如果可能的话,应该处理这些字节还是不处理?
简而言之,一个不成功的error_code
并不保证连接是死的,对于非组合操作,例如async_receive()
、bytes_transferred
在成功时将是0
或更多,如果发生错误,则始终是0
。
一个不成功的error_code
并不能正式表示该连接已正式失效。例如,TCP连接在以下情况下仍然存在:
- 通过
cancel()
取消的未完成的basic_stream_socket::async_receive()
操作将导致调用处理程序时出现boost::asio::error::operation_aborted
错误 - 全双工连接中只有一部分是
shutdown()
。例如,如果套接字的接收端关闭,那么数据仍然可以通过套接字通过连接发送
对于非组合操作,当发生错误时,bytes_transferred
将为0
。然而,0
并不表示发生了错误。例如,bytes_transferred
可以是0
,而error_code
可以在使用反应器式操作或提供空缓冲区时指示成功。StreamSocketService的async_receive()
和async_send()
文档说明:
如果操作成功完成,则会调用[handler]并传输字节数。否则使用
0
调用它。
另一方面,组合操作,例如boost::asio::async_read()
,可以使用非成功的error_code
和非零的bytes_transferred
来调用。例如,如果async_read()
操作被启动并设置为在完成之前读取1024字节,则它可以多次调用async_read_some()
。如果接收到256个字节,然后连接关闭,则async_read()
处理程序将具有非零的error_code
,并且bytes_transferred
将指示缓冲器的256个字节是有效的。
以下是一个完整的示例,演示了即使某些操作失败,连接仍能保持:
#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[] = "hellon";
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
- 通过套接字[TCP]传输数据 如何在C / C ++中打包多个整数并使用send() recv()传输数据
- 为什么std::async使用同一个线程运行函数
- 为什么可以将左值传递给"std::async",即使它引用了右值
- 使用用户定义的参数调用future/async并调用类方法
- 使用 std::async 时死锁,将来作为成员
- 为什么我不能将引用作为 std::async 的函数参数传递
- std::async from std::async in windows xp
- Google Cloud Pubsub Async Streaming API in C++
- 当对套接字 send() 的同步调用由于连接另一端丢失而被阻止时,如何恢复?
- -fno-unwind-tables 和 -fno-async-unwind-tables 不起作用 NDK clang
- std::async 如何工作:为什么它会调用这么多次复制/移动?
- ZMQ::send() 抛出异常并终止 QNX 进程.为什么以及如何从中恢复?
- std::async 不会立即调用
- async中没有匹配的函数(模板中未解析的类型)
- 在UNIX中通过recv/send交换数据时,如何正确使用缓冲区
- 如何为winsock的send()函数构造constchar*缓冲区
- std::async 如果线程是从 DLL 创建的,则会阻止进程退出?
- 使用 std::vector<std::future<int>> 和 std::async 启动几个线程时中止
- 在Visual Studio中,与std::async一起使用时不调用"thread_local"变量"析构函数,这是一个错误吗?
- C++ win32 async socket client send() issue