今天从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中可能发生了什么变化,以便在进行异步读取时导致此文件结束错误?
答案 0 :(得分:2)
Ubuntu 15.04包含3.19内核,在TUN / TAP用户API中报告了regression:
对于内核3.19,当没有数据可用时,来自非阻塞模式的TUN / TAP文件描述符的
read()
将返回0
,而不是EAGAIN
失败。
根据文档,当没有读取消息且对等体已执行有序关闭时,read()
的返回值应仅为0
。因此,Boost.Asio implementation将0
的返回视为对等方已关闭的指示,并使用错误代码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;
}