【问题标题】:How to detect a closed connection on a socket without a blocking call in boost asio如何在boost asio中检测没有阻塞调用的套接字上的关闭连接
【发布时间】:2019-10-21 16:16:52
【问题描述】:

我使用 boost asio 编写了一个 tcp 通信方案,如果我为 io_service::run() 使用单独的线程,它工作得很好。但是,通信器也应该用作 MPI 并行程序的一部分(请不要质疑这一点),其中分叉和线程不是一个好主意,并且可能不允许。

因此,通信器有一个函数work(),它调用io_service::run_one。现在,如果我直接使用async_read,它将阻塞对run_one 的调用,直到读取某些内容或发生错误。所以我编写了如下所示的check_available 函数,它首先检查套接字上是否有东西,然后在我的函数read_message_header 中调用async_read

这也很顺利,直到对等方关闭连接。不幸的是,这似乎没有被socket::available(error) 标记为eof 错误,就像async_read 中的情况一样,它返回0 作为可用字节数,因此永远不会调用read_message_header,然后会检测到eof。同时检查 socket::is_open() 并不能用于此目的,因为只有对等方的套接字被关闭,而不是此实例上的接收套接字。

void TCPConnection::check_availble() {
    if(! socket_.is_open()) {
        handle_read_error(boost::asio::error::eof);
    }
    boost::system::error_code error;
    size_t nbytes=socket_.available(error); // does not detect the eof
    if(error)
        handle_read_error(error);
    if(nbytes>0)
        read_message_header();
    else
        socket_.get_io_service().post(
                boost::bind(
                        &TCPConnection::check_availble,
                        shared_from_this()
                )
        );
}

有没有办法在没有任何阻塞调用的情况下检测 eof?

【问题讨论】:

  • 它在哪里说它应该'被socket::available(error)标记为eof错误'?您必须执行读取以检测套接字上的 EOF。

标签: c++ sockets boost-asio eof


【解决方案1】:

我有几句话要说:

调用 io_service::run_one。现在,如果我直接使用 async_read,它 将阻塞是对 run_one 的调用,直到读取某些内容或 发生错误

您可以通过创建一个伪造的work<> 对象并将其发布到io_service 队列中来轻松颠覆这种阻塞行为,因此只要有处理程序要执行,轮询就不会等待任何事件:立即返回.

谈到size_t nbytes=socket_.available(error);; avilable() 返回可读取的字节数(可能没有阻塞),正如评论中提到的:也许,您需要读取就绪字节才能看到 EOF,但 avilable() 与它无关.

【讨论】:

    猜你喜欢
    • 2015-07-20
    • 1970-01-01
    • 2011-03-31
    • 2010-09-22
    • 2019-01-18
    • 1970-01-01
    • 2016-05-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多