stream_descriptor的boost :: asio :: async_read()现在返回EOF [英] boost::asio::async_read() of stream_descriptor now returning EOF

查看:305
本文介绍了stream_descriptor的boost :: asio :: async_read()现在返回EOF的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

今天将Ubuntu从14.10升级到15.04.现在在boost::asio::async_read()boost::asio::posix::stream_descriptor或Tap/tun界面中看到了不同的行为.立即调用async_read()将返回boost::asio::error::eof.如果我忽略该错误并循环返回以启动新的async_read(),则它最终会在字节可用时读取并且应用程序将继续工作.

Upgraded Ubuntu today from 14.10 to 15.04. Now seeing different behaviour either in boost::asio::async_read(), boost::asio::posix::stream_descriptor, or tap/tun interfaces. Calling async_read() immediately returns boost::asio::error::eof. If I ignore the error and loop back up to start a new async_read() it does eventually read when bytes are available, and the application continues to work.

执行此变通方法循环的问题是,由于应用程序处于紧密循环中,因此它不断消耗对async_read()的调用,因此它现在消耗了100%的内核.

The problem with doing this workaround loop is the application now consumes 100% of a core as it sits in a tight loop continuously restarting the call to async_read().

这是我进行设置的方式:

This is how I'm setting things up:

fd = open("/dev/net/tun", O_RDWR);
....
boost::asio::posix::stream_descriptor my_stream( io_service);
my_stream.assign(fd, ec);
...
boost::asio::async_read(my_stream, my_buffer, boost::asio::transfer_at_least(16),
    [=](const EC &error, std::size_t bytes_read)
    {
        if (error) // <- this triggers with EOF error

有人知道在进行异步读取时,较新的内核(tun/tap)或boost 1.55可能发生了什么变化,从而导致此文件结束错误吗?

Anyone know what may have changed in the newer kernels (tun/tap), or boost 1.55, to cause this end-of-file error when doing asynchronous reads?

推荐答案

Ubuntu 15.04 包含3.19内核,该内核在TUN/TAP中具有报告的回归用户API:

Ubuntu 15.04 contains the 3.19 kernel, which has a reported regression in the TUN/TAP user API:

在内核3.19中,当无可用数据时,非阻塞模式下TUN/TAP文件描述符中的read()将返回0,而不是EAGAIN失败.

With kernel 3.19, a read() from a TUN/TAP file descriptor in non-blocking mode will return 0 when no data is available, rather than fail with EAGAIN.

根据文档, read() 的返回值应仅当未读取任何消息且对等方已执行有序关闭时,才为0.因此,Boost.Asio 实现将返回0视为对等方已关闭的指示,并以错误代码boost::asio::error::eof来完成async_read()操作:

Per the documentation, the return value from read() should only be 0 when no message has been read and the the peer has performed an orderly shutdown. Hence, the Boost.Asio implementation treats a return of 0 as an indication that the peer has shutdown, and completes the async_read() operation with an error code of boost::asio::error::eof:

// Read some data.
signed_size_type bytes = socket_ops::recv(s, bufs, count, flags, ec);

// Check for end of stream.
if (is_stream && bytes == 0)
{
  ec = boost::asio::error::eof;
  return true;
}

这篇关于stream_descriptor的boost :: asio :: async_read()现在返回EOF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆