提问人:Hanno 提问时间:6/6/2019 更新时间:6/26/2019 访问量:328
如何在 boost asio 中检测套接字上的关闭连接而不进行阻塞调用
How to detect a closed connection on a socket without a blocking call in boost asio
问:
我已经使用 boost asio 编写了一个 tcp 通信方案,如果我为 .但是,通信器也应该用作 MPI 并行程序的一部分(请不要质疑这一点),其中分叉和线程不是一个好主意,并且可能不允许。io_service::run()
因此,通信器具有调用 的函数。现在,如果我直接使用 ,它将阻止调用,直到读取某些内容或发生错误。因此,我编写了如下所示的函数,该函数首先检查套接字上是否有东西,然后再调用我的函数。work()
io_service::run_one
async_read
run_one
check_available
async_read
read_message_header
在对等体关闭连接之前,这也会顺利工作。不幸的是,这似乎没有被标记为 eof 错误,就像 中的情况一样,它返回 0 作为可用字节数,因此永远不会被调用,然后它会检测 eof。此外,检查也不适用于此目的,因为在此实例上只有对等方的套接字被关闭,而接收套接字则不被关闭。socket::available(error)
async_read
read_message_header
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?
答:
我有几点要说:
它调用 io_service::run_one。现在,如果我直接使用async_read,它 will be blocking 是对 run_one 的调用,直到读取某些内容或 发生错误
您可以通过创建一个假对象并将其发布到队列中来轻松破坏这种阻塞行为,因此只要有处理程序要执行,轮询就不会等待任何事件:只需立即返回即可。work<>
io_service
说 ; 返回可供读取的字节数(可能没有阻塞),并且如注释中所述:也许,您需要读取就绪字节才能查看 EOF,但与它无关。size_t nbytes=socket_.available(error);
avilable()
avilable()
评论
socket::available(error)