当error_code不为0时,连接是否正式“死”?
当error_code不为0时,读处理程序的bytesReceived参数是否可能是0以外的任何值?如果可能,是应该处理这些字节还是不处理?
答案 0 :(得分:5)
简而言之,不成功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
可以是0
,error_code
可以表示使用reactor-style operations或提供空缓冲区时的成功。 StreamSocketService州的async_receive()
和async_send()
文档说明:
如果操作成功完成,则调用[handler]并传输字节数。否则,使用
0
调用它。
另一方面,可以使用非成功error_code
和非零bytes_transferred
来调用组合操作,例如boost::asio::async_read()
。例如,如果启动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