首页 > 解决方案 > asio 的 tcp socket::async_wait() 并在此之后关闭套接字

问题描述

当在打开的套接字上我调用async_read() / read()并且对等方之后关闭套接字 - 我会eof在处理程序中得到错误,但是使用async_wait() / wait()这不会发生,处理程序调用没有错误,即error_code == 0

应该是这样吗?

例子:

#include <boost/asio.hpp>

#include <iostream>

int main() {
    const char *ip = "127.0.0.1";
    const std::uint16_t port = 44550;

    boost::asio::io_context ioctx;
    boost::asio::ip::tcp::endpoint ep{boost::asio::ip::address::from_string(ip), port};
    boost::asio::ip::tcp::acceptor acc{ioctx, ep, true};
    acc.async_accept(
        [](const boost::system::error_code &ec, boost::asio::ip::tcp::socket sock){
            if ( ec ) {
                std::cout << "accept error: " << ec.message() << std::endl;
                return;
            }

            boost::system::error_code wec;
            sock.wait(boost::asio::ip::tcp::socket::wait_read, wec);
            if ( wec ) {
                std::cout << "wait error: " << wec.message() << std::endl;
            } else {
                std::cout << "wait OK" << std::endl;
            }
        }
    );

    return ioctx.run();
}

使用 boost-1.69 和 boost-1.72 测试

标签: c++socketsboost-asio

解决方案


是的。async_wait只是等待套接字准备好。文档说,具体来说:

异步等待套接字准备好读取、准备好写入或有待处理的错误条件。

请注意,对等关闭不构成那种错误情况(感谢@DavidSchwartz 在评论中指出这一点)。

相反,随后的读取操作将显示该条件(在 Asio 中通过错误代码呈现asio::error::eof)。

这里的想法是您使用async_wait反应器样式的处理程序,并且您希望套接字的行为对于使用底层 IO 句柄的代码是透明的(例如,它可能是想要响应对等方的第三方库代码关闭,因此通过在 Asio 级别处理它来抢夺机会是没有意义的)


推荐阅读