获取本机套接字实现的非阻塞模式。
bool native_non_blocking() const;
此函数用于检索底层原生套接字的非阻塞模式。此模式对套接字对象的同步操作的行为没有影响。
true
,如果底层套接字处于非阻塞模式,并且直接的系统调用可能会因 boost::asio::error::would_block
(或等效的系统错误)而失败。
当前的非阻塞模式由套接字对象缓存。因此,如果非阻塞模式直接在原生套接字上设置,则返回值可能不正确。
此函数旨在允许将任意非阻塞系统调用封装为异步操作,并且对套接字对象的用户来说是透明的。以下示例说明了如何封装 Linux 的 sendfile
系统调用。
template <typename Handler> struct sendfile_op { tcp::socket& sock_; int fd_; Handler handler_; off_t offset_; std::size_t total_bytes_transferred_; // Function call operator meeting WriteHandler requirements. // Used as the handler for the async_write_some operation. void operator()(boost::system::error_code ec, std::size_t) { // Put the underlying socket into non-blocking mode. if (!ec) if (!sock_.native_non_blocking()) sock_.native_non_blocking(true, ec); if (!ec) { for (;;) { // Try the system call. 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; // Retry operation immediately if interrupted by signal. if (ec == boost::asio::error::interrupted) continue; // Check if we need to run the operation again. if (ec == boost::asio::error::would_block || ec == boost::asio::error::try_again) { // We have to wait for the socket to become ready again. sock_.async_wait(tcp::socket::wait_write, *this); return; } if (ec || n == 0) { // An error occurred, or we have reached the end of the file. // Either way we must exit the loop so we can call the handler. break; } // Loop around to try calling sendfile again. } } // Pass result back to user's handler. 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_wait(tcp::socket::wait_write, op); }