Наследуется от basic_socket.
Устанавливает неблокирующий режим реализации родного гнезда.
boost::system::error_code native_non_blocking(
bool mode,
boost::system::error_code & ec);
Эта функция используется для изменения режима неблокировки базового нативного гнезда. Он не влияет на поведение синхронных операций объекта разъема.
- mode
Еслиистинно
, то базовое гнездо помещается в неблокирующий режим и прямые системные вызовы могут выйти из строя сповышением:asio:ошибка:будет_блокировать
(или эквивалентная системная ошибка).
- ec
Установить, какая ошибка произошла, если таковая имеется. Еслирежим
являетсяложным
, но текущее значениенеблокировки[]
являетсяистинным
, эта функция не справляется сповышением::асио::ошибка::недействительный_аргумент
, так как сочетание не имеет смысла.
Эта функция предназначена для обеспечения инкапсуляции произвольных неблокирующих системных вызовов в виде асинхронных операций, таким образом, чтобы это было прозрачно для пользователя объекта разъема. Следующий пример иллюстрирует, как системный вызов Linuxsendfile
может быть инкапсулирован:
template <typename Handler>
struct sendfile_op
{
tcp::socket& sock_;
int fd_;
Handler handler_;
off_t offset_;
std::size_t total_bytes_transferred_;
void operator()(boost::system::error_code ec, std::size_t)
{
if (!ec)
if (!sock_.native_non_blocking())
sock_.native_non_blocking(true, ec);
if (!ec)
{
for (;;)
{
errno = 0;
int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536);
ec = boost::system::error_code(n < 0 ? errno : 0,
boost::asio::error::get_system_category());
total_bytes_transferred_ += ec ? 0 : n;
if (ec == boost::asio::error::interrupted)
continue;
if (ec == boost::asio::error::would_block
|| ec == boost::asio::error::try_again)
{
sock_.async_write_some(boost::asio::null_buffers(), *this);
return;
}
if (ec || n == 0)
{
break;
}
}
}
handler_(ec, total_bytes_transferred_);
}
};
template <typename Handler>
void async_sendfile(tcp::socket& sock, int fd, Handler h)
{
sendfile_op<Handler> op = { sock, fd, h, 0, 0 };
sock.async_write_some(boost::asio::null_buffers(), op);
}