现在返回EOF

时间:2015-04-24 07:23:16

标签: ubuntu c++11 boost-asio eof

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

执行此解决方法循环的问题是,应用程序现在消耗100%的核心,因为它处于紧密循环中,不断重新启动对async_read()的调用。

这就是我设置的方式:

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中可能发生了什么变化,以便在进行异步读取时导致此文件结束错误?

1 个答案:

答案 0 :(得分:2)

Ubuntu 15.04包含3.19内核,在TUN / TAP用户API中报告了regression

  

对于内核3.19,当没有数据可用时,来自非阻塞模式的TUN / TAP文件描述符的read()将返回0,而不是EAGAIN失败。

根据文档,当没有读取消息且对等体已执行有序关闭时,read()的返回值应仅为0。因此,Boost.Asio implementation0的返回视为对等方已关闭的指示,并使用错误代码async_read()完成boost::asio::error::eof操作:< / p>

// 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;
}