std::span
传递给 boost::asio::buffer
函数时发生的歧义重载问题。deferred
作为默认完成令牌。async_result
文档,以反映当前对 trait 特化的类型要求。local::basic_endpoint
成员函数添加了 noexcept
限定符,使其与 ip::basic_endpoint
一致。boost::asio::config
类对整数值的处理。experimental::ranged_parallel_group
中的使用后移动错误。experimental::promise
实现中不正确的默认模板参数。io_uring
实现,使其在 fork 后,如果内部描述符之前未注册,则不会尝试向 reactor 重新注册。thread_pool
默认构造函数中未初始化的成员。file_base::flags
的用法。BOOST_ASIO_DISABLE_SMALL_BLOCK_RECYCLING
时的编译错误。thread_pool::join()
以确保它停止随后使用 thread_pool::attach()
添加到池中的线程。io_uring_prep_write_fixed
和 io_uring_prep_read_fixed
用于面向流的操作时传递给它们的偏移量。async_read
。error_code
和 exception_ptr
,但可以通过 disposition_traits
类模板的特化扩展到用户类型。旨在根据 disposition 工作的通用代码不应直接使用 boost::asio::disposition_traits
,而应boost::asio::no_error
(类型为 boost::asio::no_error_t
)进行比较来测试 disposition 是否没有错误。boost::asio::to_exception_ptr
将 disposition 转换为 std::exception_ptr
。boost::asio::no_error
测试 disposition 之后,使用 boost::asio::throw_exception
抛出与 disposition 对应的异常。boost::asio::use_future
完成令牌、基于 boost::asio::awaitable<>
的协程、boost::asio::spawn()
和 boost::asio::experimental::cancellation_condition
添加了 disposition 支持。execution_context::service_maker
抽象基类。service_maker
是一个传递给执行上下文构造函数的对象,并允许在上下文构造时添加服务。已向 io_context
和 thread_pool
添加了接受 service_maker
的其他构造函数重载。添加了 boost::asio::config
。config
类提供对与执行上下文关联的配置参数的访问。该类旨在供 asio 内部使用,或供构建在 asio 之上的库或用户提供的抽象使用。这些配置参数通常用于微调行为,例如启用或禁用某些优化。在构造执行上下文(例如 io_context
)时,调用者可以选择传递 service_maker
以将具体的配置服务安装到上下文中。例如
boost::asio::io_context ctx{boost::asio::config_from_env{}};
配置参数的值使用 config
类访问,传递节、键和默认值
boost::asio::config cfg{ctx}; bool enable_locking = cfg.get("scheduler", "locking", true);
io_context
和 thread_pool
实现识别的初始配置参数集0
) - 向调度器建议应使用多少活动线程来运行完成处理程序。true
) - 可以设置为 false
以禁用调度器中的锁定,在这种情况下,必须注意不要在执行上下文或其 I/O 对象上执行并发操作。0
) - 首次尝试在不阻塞的情况下获取锁的次数。-1
) - 调度器将等待其 reactor 任务完成的最长时间。-1
) - 调度器将在空闲线程中等待其唤醒事件的最长时间。0
) - 在构造时要分配的内部 reactor I/O 对象状态的数量。true
) - 可以设置为 false
以禁用 reactor 中围绕 I/O 对象注册的锁定,在这种情况下,必须注意不要并发打开或关闭 I/O 对象。0
) - 首次尝试在不阻塞的情况下获取锁的次数。true
) - 可以设置为 false
以禁用 reactor 中每个 I/O 对象的锁定,在这种情况下,执行上下文必须是单线程的,并且必须注意不要对 I/O 操作的启动函数执行并发调用。0
) - 首次尝试在不阻塞的情况下获取锁的次数。spawn()
重载。spawn()
函数现在仅适用于 Boost.Context 中的 fiber 支持。asio::connect
重载。ip::address_v4
成员函数。ip::address_v6
成员函数。socket_base::max_connections
。const_buffers_1
和 mutable_buffers_1
。buffer_cast
。use_future_t::operator[]
。experimental::append
。experimental::prepend
。experimental::as_tuple
。experimental::deferred
。ssl::rfc2818_verification
。io_service
。io_context::work
。io_context
运行函数。io_context::reset
。io_context::service
成员函数。io_context
和 io_context::strand
中删除了已弃用的 dispatch
和 post
成员。basic_io_object
。deadline_timer
和关联类型。operator()
重载。spawn()
。co_composed
以使其不需要概念支持。ssl::detail::engine
移动赋值中的泄漏。decay
引起的 co_composed
中的问题。co_composed
中的问题。std::aligned_alloc
(如果可用)。ip::address_v6
中的整数转换警告。_alloca
所需的 <malloc.h>
的缺失包含。std::invoke_result
。file_base::append
的处理。co_spawn
的支持。spawn.hpp
标头以使其自包含。experimental::coro
实现以使用正确的取消槽。io_context::strand::wrap()
,使其返回值具有关联的执行器。constexpr
全局变量标记为 inline
。更改了 default_completion_token
trait 的主模板以选择 deferred
作为默认完成令牌。因此,大多数异步操作的启动函数默认将返回一个 deferred 异步操作。例如,从 awaitable
协程调用异步操作时,可以省略完成令牌
awaitable<void> echo(ip::tcp::socket& my_socket) { char data[1024]; for (;;) { std::size_t n = co_await my_socket.async_read_some(buffer(data)); co_await async_write(my_socket, buffer(data, n)); } }
或者在使用接受异步操作作为函数对象的操作时,例如 experimental::make_parallel_group
experimental::make_parallel_group( my_socket.async_read_some(buffer(data)), my_timer.async_wait() ).async_wait(/* ... */);
is_completion_condition
trait,并使用它为 async_read
、async_read_at
、async_write
和 async_write_at
的重载添加了缺少的默认完成令牌。is_connect_condition
trait,并使用它在完成令牌默认为空时消除 async_connect
重载的歧义。扩展了完成令牌适配器 as_tuple
、bind_allocator
、bind_cancellation_slot
、bind_executor
、bind_immediate_executor
和 redirect_error
,以允许它们用作部分完成令牌适配器。这意味着可以创建它们而无需显式提供完成令牌。相反,当适配器传递给异步操作时,它将自动确定操作的默认完成令牌并对其进行适配。例如,表达式
my_socket.async_read_some(my_buffer, as_tuple)
将返回一个 deferred 异步操作,其完成参数打包在一个元组中。它们也可以使用 deferred
操作的管道运算符应用
error_code e; co_await (async_write(my_socket, my_buffer) | redirect_error(e));
添加了 cancel_after
和 cancel_at
完成令牌适配器。这些适配器可用于适配任何异步操作,以在指定的持续时间之后或在绝对时间点发出取消信号。例如
my_socket.async_read_some(my_buffer, cancel_after(std::chrono::seconds(10), [](error_code e, std::size_t n) { // ... }));
此取消在内部使用 basic_waitable_timer
实现。默认情况下,此计时器是使用异步操作的 I/O 执行器创建的。如果操作确实指定了其 I/O 执行器,则可以显式提供计时器
my_socket.async_read_some(my_buffer, cancel_after(my_timer, std::chrono::seconds(10), [](error_code e, std::size_t n) { // ... }));
这些适配器也可以用作部分完成令牌适配器,例如在
co_await my_socket.async_read_some(my_buffer, cancel_after(5s));
或者
co_await ( async_write(my_socket, my_buffer) | as_tuple | cancel_after(std::chronos::seconds(10) );
或者适配其他部分完成令牌适配器
co_await my_socket.async_read_some(my_buffer, cancel_after(5s, as_tuple));
请注意,由于基于计时器的实现引入了并行 async_wait
操作,因此调用者有责任确保异步操作在隐式或显式 strand 中执行。
async_compose
和 co_composed
,以正确指示它们是否具有 I/O 执行器。co_composed
移出了 experimental
命名空间。添加了 composed
,它从有状态的实现创建启动函数对象。它类似于 co_composed
,但用于常规函数对象而不是 C++20 协程。例如
struct async_echo_implementation { tcp::socket& socket_; mutable_buffer buffer_; enum { starting, reading, writing } state_; template <typename Self> void operator()(Self& self, error_code error, std::size_t n) { switch (state_) { // ... } } }; template <typename CompletionToken> auto async_echo(tcp::socket& socket, mutable_buffer buffer, CompletionToken&& token) { return async_initiate<CompletionToken, void(error_code, std::size_t)>( composed( async_echo_implementation{socket, buffer, async_echo_implementation::starting}, socket), token, error_code{}, 0); }
async_compose
函数已更改为 composed
的薄包装器。但是,与 async_compose
不同,composed
允许在操作启动时将参数传递给有状态的实现。
detached
完成令牌以使其与具有多个完成签名的异步操作一起使用。async_initiate
以允许完成签名的空可变参数列表,这将表明异步操作永远不会完成。添加了 async_initiate
的重载,这些重载会自动推断完成令牌的类型。例如
async_initiate(co_composed(/* ... */), detached, arg_1, arg_2);
将从参数 detached
推断令牌类型。
async_immediate
,它实现了一个微不足道的异步操作,该操作会立即完成,如果可用,则使用关联的立即执行器。它旨在在异步组合中使用,以使其更容易提供优化的立即完成。async_immediate
指定立即完成。associator
trait 的部分特化。deferred
实现,以确保正确传播包装的启动函数对象的 copyability。experimental::coro
与 clang 15 的兼容性。ioctl
修改已分配的套接字或描述符的非阻塞模式,因为它们可能来自外部源。F_SETFL
调用 fcntl
。async_wait
操作时,不要启用非阻塞模式。BOOST_ASIO_NO_DYNAMIC_BUFFER_V1
时 read_until
正则表达式支持。co_spawn
以将取消导致的异常正确传播到完成处理程序。std::launder
的调用,以修复 awaitable<>
内部存储中的未定义行为。file_base::append
标志的缺失处理。ioctl
失败时它们将回退到 fcntl
的情况。experimental::coro
时发生的编译错误。async_result
主模板的概念检查,以正确处理左值限定的完成签名。bind_allocator
、bind_executor
、bind_immediate_executor
和 bind_cancellation_slot
完成令牌适配器来相互适配时可能出现的一些编译错误。experimental::ranged_parallel_group
操作,以便在调用完成处理程序时移动 completion_order
向量。boost/asio/experimental/parallel_group.hpp
标头,使其自包含。ip::basic_resolver_query
、io_context::strand
和 coroutine
上已弃用的隐式复制构造函数的一些警告。any_completion_handler
和使用 BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT
进行编译之间的兼容性。any_completion_handler
对象的关联器时可能发生的崩溃。ssl::stream<>
类的 async_handshake
操作,使其可以使用默认的完成令牌。boost::asio::execution
命名空间中删除了已弃用的功能。std::bind
之间的兼容性。try_send_via_dispatch
和 try_send_n_via_dispatch
函数。any_completion_handler
之间的兼容性。std::exception_ptr
开头的异步操作一起使用时,会导致程序终止的问题。bind_allocator
、bind_cancellation_slot
和 bind_immediate_executor
,使其在适配的 async_result
特化中不需要 return_type
类型别名。co_spawn
操作的取消支持中的对象生命周期问题而导致的潜在崩溃。thread_local
关键字。experimental::co_composed
的每个操作取消行为的文档,以正确说明默认情况下启用终端取消。async_compose
的每个操作取消行为。bind_immediate_executor
添加到 Completion Token Adapters 概述中。any_completion_handler
添加了缺失的与 associated_immediate_executor
的兼容性。any_executor
调用 query
、require
或 prefer
时发生的空指针解引用问题。experimental::coro
中添加了一个变通方法。io_uring
支持时,添加了对最低 Linux 内核版本 5.10 的编译时检查。experimental::basic_channel
和 experimental::basic_concurrent_channel
的转换移动构造函数中的编译错误。signal_set
错误处理代码路径上的内存泄漏。bad_address_cast
以避免使用已弃用的隐式复制构造函数。dev_poll_reactor
后端中的复制/粘贴错误。io_uring
后端,以确保用于实现 io_context::run_for
和 io_context::run_until
的内部超时操作被正确清理。co_spawn
实现入口点中的一些重复状态,从而减少了内存消耗。awaitable<>
的协程的 co_await
异步操作(打包为函数对象)的能力,添加了缺失的处理程序跟踪源位置支持。co_composed
添加了缺失的处理程序跟踪源位置支持。const_buffers_1
和 mutable_buffers_1
类型传递给 asio::buffer()
时,错误地选择了连续迭代器重载。ssl::stream<>
)之间的兼容性。ip::address_v4::to_ulong
标记为已弃用。basic_socket_acceptor::async_accept
概念要求检查,使其与具有推导返回类型的 lambda 兼容。use_future
兼容性 traits 中使用的功能检测宏。as_tuple
与旧式完成令牌的兼容性。redirect_error
与新完成令牌的兼容性。this_coro
以防止意外的布尔表达式的 co_await
。experimental::use_coro
实现中的结果处理。is_async_operation
和 completion_signature_of
的可变参数模板模拟。experimental::promise
中移动后结果的不正确重用。experimental::coro
与自定义分配器的使用。io_uring
时内部 I/O 对象结构的清理。any_completion_handler<>
、co_composed
和立即完成支持。添加了自定义操作完成时立即完成时的完成处理程序的执行的能力。此更改添加了 associated_immediate_executor
关联器 traits、bind_immediate_executor
函数和 immediate_executor_binder
适配器。当受支持的操作立即完成时(即在启动函数内),将获取关联的立即执行器,并通过该执行器传递完成处理程序,就像在该执行器上使用 asio::dispatch
一样。默认情况下,立即执行器传递完成处理程序,就像通过操作的 I/O 执行器使用 asio::post
一样。例如,为了允许对 async_read_some
操作的完成处理程序进行递归调用,我们可以指定立即完成通过 system_executor
传递
my_socket.async_read_some(my_buffer, bind_immediate_executor( system_executor(), [](error_code e, size_t n) { // ... } ) );
reactor 类型的套接字和描述符上的异步操作,以及通道上的异步操作,目前支持立即执行。
为缓冲区类型添加了用户定义的字面量。_buf
字面量后缀在命名空间 asio::buffer_literals
中定义,可用于从字符串、二进制整数和十六进制整数文字创建 const_buffer 对象。这些缓冲区字面量可以任意长。例如
using namespace asio::buffer_literals; asio::const_buffer b1 = "hello"_buf; asio::const_buffer b2 = 0xdeadbeef_buf; asio::const_buffer b3 = 0x0123456789abcdef0123456789abcdef_buf; asio::const_buffer b4 = 0b1010101011001100_buf;
与缓冲区字面量关联的内存在其程序生命周期内有效。这意味着缓冲区可以安全地用于异步操作
async_write(my_socket, "hello"_buf, my_handler);
local::seq_packet_protocol
来表示 AF_UNIX
和 SOCK_SEQPACKET
。通过 signal_set::add
的可选参数公开了 sigaction()
标志。注册信号时,现在可以传递标志来指定与信号关联的行为。这些标志在新类 signal_set_base 中指定为枚举类型,并传递给底层 sigaction()
调用。例如
asio::signal_set sigs(my_io_context); sigs.add(SIGINT, asio::signal_set::flags::restart);
除非目标操作系统支持 sigaction()
,否则指定 flags::dont_care
以外的标志将失败。由于信号注册是全局的,因此冲突的标志(多个注册传递了与 flags::dont_care
不同的标志)也会导致错误。
allocator_binder
、executor_binder
和 cancellation_slot_binder
以支持检测未专门化的关联器。associated_cancellation_slot<reference_wrapper>::get()
中的歧义。awaitable
对包含 std::exception_ptr
的完成签名的处理。experimental::channel
在 cancel
后的 try_send
失败。thread_pool::join()
死锁。io_uring
时管道 release()
。io_uring
后端中的数据初始化问题。get_associated_executor
的执行上下文重载中的悬空引用问题。experimental::channel
关闭时,仍然可以接收缓冲的消息。any_completion_handler
赋值运算符以使其正常工作。any_completion_handler
的构造函数,以防止意外复制uint64_t
作为 OpenSSL 选项,以匹配 OpenSSL 3。deferred
与多个完成签名的互操作性。any_completion_handler
。spawn
和 co_spawn
实现,以在正确的执行器上分派取消处理程序。当完成处理程序使用指定的(即非默认)关联执行器时,取消处理程序将分派到传递给 spawn()
或 co_spawn()
的执行器。spawn
以确保通过正确的执行器分派完成处理程序。snprintf
而不是 sprintf
,以解决弃用警告。co_spawn
和 any_completion_handler
之间的兼容性。select_reactor::run
的参数。BOOST_ASIO_DISABLE_SMALL_BLOCK_RECYCLING
时的编译错误。std::invoke_result
。experimental::coro
实现中添加了缺失的 include。io_uring
添加到实现说明中。添加了 consign
完成令牌适配器,可用于将附加值附加到完成处理程序。这通常用于至少保留对象的一个副本(例如智能指针),直到调用完成处理程序。例如
auto timer1 = std::make_shared<asio::steady_timer>(my_io_context); timer1->expires_after(std::chrono::seconds(1)); timer1->async_wait( asio::consign( [](boost::system::error_code ec) { // ... }, timer1 ) );
添加了 any_completion_handler<>
,可用于类型擦除完成处理程序。一个典型的用例是启用异步操作实现的分开编译。例如
// Header file: void async_sleep_impl( asio::any_completion_handler<void(boost::system::error_code)> handler, asio::any_io_executor ex, std::chrono::nanoseconds duration); template <typename CompletionToken> inline auto async_sleep(asio::any_io_executor ex, std::chrono::nanoseconds duration, CompletionToken&& token) { return asio::async_initiate< CompletionToken, void(boost::system::error_code)>( async_sleep_impl, token, std::move(ex), duration); } // Separately compiled source file: void async_sleep_impl( asio::any_completion_handler<void(boost::system::error_code)> handler, asio::any_io_executor ex, std::chrono::nanoseconds duration) { auto timer = std::make_shared<asio::steady_timer>(ex, duration); timer->async_wait(asio::consign(std::move(handler), timer)); }
添加了 experimental::co_composed
,它有助于使用 C++20 协程轻量级实现用户定义的异步操作。以下示例说明了一个简单的异步操作,该操作根据协程实现了一个 echo 协议
template <typename CompletionToken> auto async_echo(tcp::socket& socket, CompletionToken&& token) { return asio::async_initiate< CompletionToken, void(boost::system::error_code)>( asio::experimental::co_composed< void(boost::system::error_code)>( [](auto state, tcp::socket& socket) -> void { try { state.throw_if_cancelled(true); state.reset_cancellation_state( asio::enable_terminal_cancellation()); for (;;) { char data[1024]; std::size_t n = co_await socket.async_read_some( asio::buffer(data), asio::deferred); co_await asio::async_write(socket, asio::buffer(data, n), asio::deferred); } } catch (const boost::system::system_error& e) { co_return {e.code()}; } }, socket), token, std::ref(socket)); }
添加了基于范围的 experimental::make_parallel_group() 重载,可用于启动动态大小的异步操作集,其中所有操作都是相同的类型。例如
using op_type = decltype( socket1.async_read_some( asio::buffer(data1), asio::deferred ) ); std::vector<op_type> ops; ops.push_back( socket1.async_read_some( asio::buffer(data1), asio::deferred ) ); ops.push_back( socket2.async_read_some( asio::buffer(data2), asio::deferred ) ); asio::experimental::make_parallel_group(ops).async_wait( asio::experimental::wait_for_all(), []( std::vector<std::size_t> completion_order, std::vector<boost::system::error_code> e, std::vector<std::size_t> n ) { for (std::size_t i = 0; i < completion_order.size(); ++i) { std::size_t idx = completion_order[i]; std::cout << "socket " << idx << " finished: "; std::cout << e[idx] << ", " << n[idx] << "\n"; } } );
感谢 Klemens Morgenstern 提供了此实现的一部分。
any_completion_executor
,它是与完成处理程序关联的执行器的类型擦除包装器。context
查询。execution::any_executor<>
和 any_io_executor
添加了 noexcept 构造函数重载。execution::any_executor
对象的表示,以提高复制和移动操作的性能。std::reference_wrapper
添加了 associated_cancellation_slot
特化。get
函数使用推导的返回类型。spawn
实现以捕获未处理的异常,并在派生的“线程”外部重新抛出它们。spawn
“线程”对象的清理。execution::execute
自定义点。使用 execute
作为成员函数。parallel_group
示例。experimental::channel_traits
特化中的歧义。R(error_code)
签名添加了专门的通道实现。async_compose
'self' 对象上的 cancelled()
公开。async_compose
'self' 对象。release()
的实现。experimental::coro
启用了延迟等待,规范化了 experimental::use_coro
,并修复了分配器处理。这意味着 use_coro
不会返回 coro 对象,就像 use_awaitable 一样,即,它是一种开销,可以为我们带来类型擦除。现在可以通过在 coro 签名中包含 allocator_arg
来为 coro
设置分配器。experimental::promise
并使其成为异步操作对象。post
/defer
重载,使其能够要求 blocking.never
。ioctl
设置非阻塞模式时失败并显示 ENOTTY
时,回退到 fcntl
。decltype
。此更改为 C++11 启用了新形式的 async_result
,其中返回类型可以因操作而异。append
、prepend
、as_tuple
和 deferred
移动到 boost::asio
命名空间,并使它们与 C++11 兼容。这些不再是实验性功能,尽管为了向后兼容,这些名称已暂时保留在 boost::asio::experimental
命名空间下。std::span
)添加了 buffer()
重载。为基于 awaitable<>
的协程添加了直接 co_await
打包为函数对象的操作的能力。例如,使用 deferred
asio::awaitable<void> my_coro() { asio::steady_timer timer(co_await asio::this_coro::executor); timer.expires_after(std::chrono::seconds(5)); co_await timer.async_wait(asio::deferred); }
或使用手工制作的函数对象
asio::awaitable<void> my_coro() { asio::steady_timer timer(co_await asio::this_coro::executor); timer.expires_after(std::chrono::seconds(5)); co_await [&](auto&& token) { return timer.async_wait(std::forward<decltype(token)>(token)); }; }
更改了 spawn()
以使其成为基于完成令牌的异步操作。这引入了符合异步操作要求的新 spawn()
重载。例如
std::string do_read(asio::yield_context yield) { char data[1024]; size_t n = my_socket.async_read_some(asio::buffer(data), yield); return std::string(data, n); } asio::spawn(my_executor, do_read, [](std::exception_ptr ex, std::string result) { // ... });
这些新的 spawn()
重载支持取消,并且还增强了 basic_yield_context
完成令牌以支持仅移动和可变参数结果类型。当目标为 C++11 及更高版本时,这些函数直接根据 Boost.Context 实现。现有的重载已保留但已弃用。
添加了 is_async_operation
trait 和 async_operation
概念。is_async_operation
trait 可用于确定是否可以调用函数对象和可选参数来启动异步操作。例如,当使用 deferred
时
auto d = my_timer.async_wait(asio::deferred); static_assert(asio::is_async_operation<decltype(d)>::value);
或使用手工制作的异步操作
struct my_async_op { asio::ip::tcp::socket& socket_ = ...; template <typename Token> auto operator()(asio::const_buffer data, Token&& token) { return asio::async_write(socket_, data, std::forward<Token>(token)); } }; static_assert( asio::is_async_operation< my_async_op, asio::const_buffer>::value);
添加了 completion_signature_of
trait。completion_signature_of
trait(以及相应的类型别名 completion_signature_of_t
)可用于确定异步操作的完成签名。例如
auto d = my_timer.async_wait(asio::deferred); using sig = asio::completion_signature_of<decltype(d)>::type; // sig is void(error_code)
或使用手工制作的异步操作
struct my_async_op { asio::ip::tcp::socket& socket_ = ...; template <typename Token> auto operator()(asio::const_buffer data, Token&& token) { return asio::async_write(socket_, data, std::forward<Token>(token)); } }; using sig = asio::completion_signature_of< my_async_op, asio::const_buffer>::type; // sig is void(error_code, size_t)
object_handle
、Windows 流句柄和 Windows 随机访问句柄添加了转换移动构造/赋值。release()
成员函数。Endpoint
实现的支持,这些实现从其 data()
成员函数返回 void
指针,如记录的 Endpoint
类型要求所述。experimental::promise
中删除了 all()
和 race()
,因为 experimental::parallel_group
涵盖了此功能。-masm=intel
的兼容性。shutdown()
调用对于同一套接字上的某些其他同步操作是线程安全的。std::invoke_result
的检测。experimental::parallel_group
启动错误地移动了参数而不是转发它们。post()
、dispatch()
和 defer()
实现中的排序问题,其中关联的分配器可能从已移动的完成处理程序中获得。awaitable<>
实现,以将来自等待的启动函数的异常通过当前完成处理程序传播。gcc
7 的 std::aligned_alloc
检测。std::aligned_storage
。std::aligned_alloc
检测。experimental::coro
实现中删除了错误的断言。select_reactor
的实现,以确保由于未能重新创建其中断器的套接字而导致的任何异常都将允许通过 io_context::run()
传播出去。async_result
形式。fopen()
相同的共享模式打开文件。EAGAIN
作为正在进行的连接操作的指示。experimental::basic_channel::reset()
和 experimental::basic_concurrent_channel::reset()
,以便它们对于未关闭的通道也能正常工作。experimental::promise
操作 race()
和 all()
中潜在的未定义行为。co_spawn
实现,以通过指定的执行器显式分派取消信号(如果完成处理程序有自己的关联执行器)。make_strand()
、make_work_guard()
、ip::address_v4
、ip::address_v6
、experimental::basic_channel
和 experimental::basic_concurrent_channel
添加了更详细的参考文档。async_compose
、experimental::deferred
、experimental::parallel_group
、experimental::promise
、通道和完成令牌适配器。io_context
参考文档,以便在防止 io_context
耗尽工作时使用 executor_work_guard
。deadline_timer
的引用。bind_allocator
,以简化将自定义分配器与完成令牌或处理程序关联的操作。file_base::sync_all_on_write
标志,该标志在 POSIX 上映射到 O_SYNC
,在 Windows 上映射到 FILE_FLAG_WRITE_THROUGH
。basic_file::release()
的缺失实现。recycling_allocator
作为公共接口的一部分。nodiscard
属性bind_allocator()
bind_cancellation_slot()
bind_executor()
buffer()
dynamic_buffer()
experimental::append()
experimental::as_single()
experimental::as_tuple()
experimental::make_parallel_group()
experimental::prepend()
get_associated_allocator()
get_associated_cancellation_slot()
get_associated_executor()
make_work_guard()
SSL*
采纳到 ssl::stream<>
中的支持。BOOST_ASIO_NO_TS_EXECUTORS
,也启用了 executor_work_guard<>
。bind_cancellation_slot
与旧式完成令牌的兼容性。bind_executor
与旧式完成令牌的兼容性。associator
对 experimental::append
和 experimental::prepend
的特化,以正确传播关联的分配器、执行器和取消槽。awaitable
中的“零作为空指针常量”警告。asio/io_context.hpp
时,并发提示预处理器宏可用。associated_allocator
模板未正确检测嵌套 T::allocator_type
的问题。io_uring
实现 async_receive_from
操作。io_uring
实现 write_some_at
操作。io_uring
实现,以正确检查它是否不是默认值,然后再向反应器注册。io_uring
时的循环包含问题。experimental::coro
的按操作取消功能,以在每次操作完成时清除槽。experimental::promise
的类型擦除完成处理程序中的内存管理。ssl::stream
的移动 operator=
实现。any_io_executor
实现,使其在定义了 BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT
和 BOOST_ASIO_SEPARATE_COMPILATION
时也能工作。sockatmark()
系统调用时 basic_socket::at_mark()
的实现。dispatch()
、post()
和 defer()
的文档,以涵盖旧的和新的执行器形式。BOOST_ASIO_HAS_IO_URING
和 BOOST_ASIO_DISABLE_EPOLL
来启用。BOOST_ASIO_HAS_IO_URING
将启用后端,而不会将其用于现有的 I/O 对象。这允许它用于需要 io_uring 支持的 I/O 对象,例如文件。liburing
库。将 -luring
添加到您的链接库列表中。添加了对文件的支持。这引入了用于面向流和随机访问文件的新类。例如,要写入新创建的面向流的文件
asio::stream_file file( my_io_context, "/path/to/file", asio::stream_file::write_only | asio::stream_file::create | asio::stream_file::truncate); file.async_write_some(my_buffer, [](error_code e, size_t n) { // ... });
或从随机访问文件读取
asio::random_access_file file( my_io_context, "/path/to/file", asio::random_access_file::read_only); file.async_read_some_at(1234, my_buffer, [](error_code e, size_t n) { // ... });
此功能当前支持 Windows 上的 I/O 完成端口和 Linux 上的 io_uring(定义 BOOST_ASIO_HAS_IO_URING
以启用)。
添加了对可移植管道的支持。此更改添加了对 POSIX 和 Windows 上管道的支持(当 I/O 完成端口可用时)。例如,要创建和使用连接的一对管道对象
asio::readable_pipe read_end; asio::writable_pipe write_end; asio::connect_pipe(read_end, write_end); write_end.async_write_some(my_write_buffer, [](error_code e, size_t n) { // ... }); read_end.async_read_some(my_read_buffer, [](error_code e, size_t n) { // ... });
添加了对注册缓冲区的支持。mutable_registered_buffer
和 const_registered_buffer
类是表示注册缓冲区的缓冲区序列类型。这些缓冲区通过首先执行缓冲区注册来获得
auto my_registration = asio::register_buffers( my_execution_context, my_buffer_sequence);
注册对象必须在需要缓冲区注册的时间内保持。提供的缓冲区序列表示将要注册的内存位置,调用者必须确保它们在注册期间保持有效。当注册对象被销毁时,注册会自动删除。每个执行上下文最多可以有一个活动注册。
注册对象是注册缓冲区的容器。可以通过迭代容器或通过直接索引访问从中获取缓冲区
asio::mutable_registered_buffer my_buffer = my_registration[i];
然后可以将注册缓冲区直接传递给操作
asio::async_read(my_socket, my_buffer, [](error_code ec, size_t n) { // ... });
当与描述符、文件、管道和套接字上的读取和写入操作一起使用时,缓冲区注册支持 io_uring 后端。为了可移植性,该工具可以在其他平台上使用,但注册缓冲区将表现为普通缓冲区。
添加了对通道的实验性支持。这添加了模板 experimental::basic_channel
和 experimental::basic_concurrent_channel
,别名为 experimental::channel
和 experimental::concurrent_channel
。通道可用于将完成作为消息发送。例如
// Create a channel with no buffer space. channel<void(error_code, size_t)> ch(ctx); // The call to try_send fails as there is no buffer // space and no waiting receive operations. bool ok = ch.try_send(asio::error::eof, 123); assert(!ok); // The async_send operation is outstanding until // a receive operation consumes the message. ch.async_send(asio::error::eof, 123, [](error_code ec) { // ... }); // The async_receive consumes the message. Both the // async_send and async_receive operations complete // immediately. ch.async_receive( [](error_code ec, size_t n) { // ... });
experimental::coro
的改进。coro
任务添加了 co_spawn
。clang
上禁用了 aligned_alloc
。ip::network_v4::canonical()
使用更快的实现。io_context
执行器的大小减小到单个指针。execution::any_executor
和 any_io_executor
的小对象缓冲区大小。gcc
和 clang
的兼容性。ssl
工具发出的错误消息。bind_executor
与完成令牌的兼容性。BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT
时的构建错误。awaitable<>
添加了缺失的移动赋值运算符。experimental::parallel_group
中发生的清理问题。CancellationSlot
(一个轻量级的取消通道,通过新的 associated_cancellation_slot
关联器指定)来实现的。具体的 CancellationSlot
实现以 cancellation_signal
和 cancellation_slot
类的形式提供。与 bind_cancellation_slot
辅助函数结合使用,这些可以用于将取消挂钩到异步操作中。但是,应该注意的是,这些类是取消的低级构建块,大多数用例应该使用更高级别的取消抽象,例如 experimental::parallel_group
或新的 awaitable
逻辑运算符(见下文)。取消单个操作或组合操作的能力目前受以下支持:async_read
和 async_write
async_compose
的组合awaitable
的 C++20 协程experimental::coro
的 C++20 协程(见下文)experimental::parallel_group
操作(见下文)experimental::promise
类(见下文)添加了 associator
特性。associator
特性用于通用地转发关联器,例如 associated_executor
和 associated_allocator
,通过中间完成处理程序。例如
template <typename Handler> struct intermediate_handler { Handler handler_; template <typename... Args> void operator()(Args&... args) { // ... } }; namespace asio { template < template <typename, typename> class Associator, typename Handler, typename DefaultCandidate> struct associator< Associator, intermediate_handler<Handler>, DefaultCandidate> { using type = typename Associator<Handler, DefaultCandidate>::type; static type get( const intermediate_handler<Handler>& h, const DefaultCandidate& c = DefaultCandidate()) noexcept { return Associator<Handler, DefaultCandidate>::get( h.handler_, c); } }; } // namespace asio
添加了对具有多个完成签名的异步操作的支持。完成签名还可以指定它们是 noexcept
,以及它们是否是左值可调用(因此不“消耗”完成处理程序)或右值可调用(因此确实“消耗”处理程序,表示异步操作结束)。例如
auto my_async_operation(..., asio::completion_token_for< void(intermediate_result_type) & noexcept, void(final_result_type) && > auto&& token) { // ... }
为 awaitable<>
添加了 operator&&
和 operator||
。逻辑运算符 ||
和 &&
已为 awaitable<>
重载,以允许协程以并行方式轻松等待。
当使用 &&
等待时,co_await
表达式会等待直到两个操作都成功完成。作为“短路”评估,如果一个操作因异常而失败,则另一个操作会立即取消。例如
std::tuple<std::size_t, std::size_t> results = co_await ( async_read(socket, input_buffer, use_awaitable) && async_write(socket, output_buffer, use_awaitable) );
当使用 ||
等待时,co_await
表达式会等待直到任一操作成功。作为“短路”评估,如果一个操作成功且未抛出异常,则另一个操作会立即取消。例如
std::variant<std::size_t, std::monostate> results = co_await ( async_read(socket, input_buffer, use_awaitable) || timer.async_wait(use_awaitable) );
可以通过添加 #include
来启用运算符
#include <boost/asio/experimental/awaitable_operators.hpp>
然后将 experimental::awaitable_operators
命名空间的内容引入作用域
using namespace asio::experimental::awaitable_operators;
添加了 experimental::as_tuple
完成令牌适配器。as_tuple
完成令牌适配器可用于指定应将完成处理程序参数组合到单个元组参数中。as_tuple
适配器可以与 use_awaitable
和结构化绑定结合使用,如下所示
auto [e, n] = co_await socket.async_read_some( asio::buffer(data), as_tuple(use_awaitable));
或者,它可以像这样用作默认完成令牌
using default_token = as_tuple_t<use_awaitable_t<>>; using tcp_socket = default_token::as_default_on_t<tcp::socket>; // ... awaitable<void> do_read(tcp_socket socket) { // ... auto [e, n] = co_await socket.async_read_some(asio::buffer(data)); // ... }
添加了 experimental::append
完成令牌适配器。append
完成令牌适配器可用于在完成签名的末尾传递其他完成处理程序参数。例如
timer.async_wait( asio::experimental::append( [](boost::system::error_code ec, int i) { // ... }, 42) ); std::future<int> f = timer.async_wait( asio::experimental::append( asio::use_future, 42 ) );
添加了 experimental::prepend
完成令牌适配器。prepend
完成令牌适配器可用于在现有完成处理程序参数之前传递其他参数。例如
timer.async_wait( asio::experimental::prepend( [](int i, boost::system::error_code ec) { // ... }, 42) ); std::future<std::tuple<int, boost::system::error_code>> f = timer.async_wait( asio::experimental::prepend( asio::use_future, 42 ) );
添加了 experimental::deferred
完成令牌。deferred
完成令牌接受对异步操作启动函数的调用,并将其转换为接受完成令牌的函数对象。例如
auto deferred_op = timer.async_wait( asio::experimental::deferred); ... std::move(deferred_op)( [](boost::system::error_code ec){ ... });
或者
auto deferred_op = timer.async_wait( asio::experimental::deferred); ... std::future<void> = std::move(deferred_op)( asio::use_future);
延迟令牌还支持链式调用,以创建简单的组合
auto deferred_op = timer.async_wait( asio::experimental::deferred( [&](boost::system::error_code ec) { timer.expires_after( std::chrono::seconds(1)); return timer.async_wait( asio::experimental::deferred); }); ... std::future<void> = std::move(deferred_op)(asio::use_future);
添加了 experimental::parallel_group
类和 experimental::make_parallel_group
函数。此实用程序可用于启动并行执行的工作,并等待一个或所有操作完成。parallel_group
实现了对未完成操作的自动取消。例如
experimental::make_parallel_group( [&](auto token) { return stream.async_read_some(asio::buffer(data), token); }, [&](auto token) { return timer.async_wait(token); } ).async_wait( experimental::wait_for_one(), []( std::array<std::size_t, 2> completion_order, boost::system::error_code ec1, std::size_t n1, boost::system::error_code ec2 ) { // ... } );
可以使用四个提供的函数对象 wait_for_all
、wait_for_one
、wait_for_one_success
和 wait_for_one_error
之一或使用自定义函数来指定组的完成条件。parallel_group
类也可以与 deferred
结合使用,如下所示
experimental::make_parallel_group( stream.async_read_some(asio::buffer(data), experimental::deferred), timer.async_wait(experimental::deferred) ).async_wait( // ... );
注意:为了最大的灵活性,parallel_group
不会自动将执行器传播到组内的操作。
添加了 experimental::promise
。promise
类型允许异步操作的抢先执行和同步。例如
auto promise = async_read( stream, asio::buffer(my_buffer), asio::experimental::use_promise); ... do other stuff while the read is going on ... promise.async_wait( // completion the operation [](error_code ec, std::size_t bytes_read) { ... });
如果不再需要结果,可以安全地忽略 Promise。可以将不同的操作组合起来,以等待所有操作完成或等待一个操作完成(并取消其余操作)。例如,要等待一个完成
auto timeout_promise = timer.async_wait( asio::experimental::use_promise); auto read_promise = async_read( stream, asio::buffer(my_buffer), asio::experimental::use_promise); auto promise = asio::experimental::promise<>::race( timeout_promise, read_promise); promise.async_wait( [](std::variant<error_code, std::tuple<error_code, std::size_t>> v) { if (v.index() == 0) {} //timed out else if (v.index() == 1) // completed in time });
或等待所有完成
auto write_promise = async_write( stream, asio::buffer(my_write_buffer), asio::experimental::use_promise); auto read_promise = async_read( stream, asio::buffer(my_buffer), asio::experimental::use_promise); auto promise = asio::experimental::promise<>::all( write_promise, read_promise); promise.async_wait( [](std::tuple<error_code, std::size_t> write_result, std::tuple<error_code, std::size_t> read_result) { });
感谢 Klemens Morgenstern 为此功能做出的贡献。
添加了 experimental::coro
类模板。coro
类型是用于可恢复函数的 C++20 协程原语,能够将异步等待 (co_await
) 和让步 (co_yield
) 组合到单个有状态的控制流中。例如
#include <boost/asio.hpp> #include <boost/asio/experimental/coro.hpp> using asio::ip::tcp; asio::experimental::coro<std::string> reader(tcp::socket& sock) { std::string buf; while (sock.is_open()) { std::size_t n = co_await asio::async_read_until( sock, asio::dynamic_buffer(buf), '\n', asio::experimental::use_coro); co_yield buf.substr(0, n); buf.erase(0, n); } } asio::awaitable<void> consumer(tcp::socket sock) { auto r = reader(sock); auto msg1 = co_await r.async_resume(asio::use_awaitable); std::cout << "Message 1: " << msg1.value_or("\n"); auto msg2 = co_await r.async_resume(asio::use_awaitable); std::cout << "Message 2: " << msg2.value_or("\n"); } asio::awaitable<void> listen(tcp::acceptor& acceptor) { for (;;) { co_spawn( acceptor.get_executor(), consumer(co_await acceptor.async_accept(asio::use_awaitable)), asio::detached); } } int main() { asio::io_context ctx; tcp::acceptor acceptor(ctx, {tcp::v4(), 54321}); co_spawn(ctx, listen(acceptor), asio::detached); ctx.run(); }
感谢 Klemens Morgenstern 为此功能做出的贡献。
ssl::stream<>
添加了移动赋值。co_spawn
,以将协程的初始步骤分派到执行器,并且仅当协程没有以其他方式执行上下文切换(即对异步操作的 co_await
)时才 post
完成处理程序。any_executor
和 any_io_executor
启用了额外的优化。awaitable<>
添加了 nodiscard
属性。BOOST_ASIO_RECYCLING_ALLOCATOR_CACHE_SIZE
宏来指定。std::system_error
消息解决方法。use_awaitable_t::executor_with_default
中的递归模板实例化问题。any_io_executor
相等运算符,以正确返回基于目标执行器的结果。strand<>
以避免使用可能已移动的执行器。gcc
测试不用于 clang
。clang
的协程支持。OPENSSL_NO_SSL_INTERN
时与最新 LibreSSL 的兼容性。posix::basic_stream_descriptor
移动操作,使其与非默认执行器一起工作。ip::scope_id_type
类型别名。ip::port_type
类型别名。std::hash
特化。ip::basic_endpoint<>
添加了 std::hash
特化。any_io_executor
更改为“强类型定义”样式的类。experimental::as_single
,使其与处理程序挂钩弃用一起工作。socket()
在 macOS/FreeBSD 上失败,则不会覆盖 errno
。io_context
和 thread_pool
执行器的工作跟踪。call_stack
对象仅从实现文件中访问。blocking.always
属性与 strand<>
一起使用,因为它没有产生正确的语义。asio/impl/src.cpp
。connect_pair
函数除外(该函数将失败并显示 operation_not_supported 错误)。ip::basic_resolver
添加了执行器转换构造和赋值。添加了 experimental::as_single
完成令牌适配器。as_single
完成令牌适配器可用于指定应将完成处理程序参数组合到单个参数中。对于具有单个参数的完成签名,该参数按原样传递。对于具有两个或多个参数的签名,这些参数会组合成一个元组。as_single
适配器可以与 use_awaitable
和结构化绑定结合使用,如下所示
auto [e, n] = co_await socket.async_read_some( boost::asio::buffer(data), as_single(use_awaitable));
或者,它可以像这样用作默认完成令牌
using default_token = as_single_t<use_awaitable_t<>>; using tcp_socket = default_token::as_default_on_t<tcp::socket>; // ... awaitable<void> do_read(tcp_socket socket) { // ... auto [e, n] = co_await socket.async_read_some(boost::asio::buffer(data)); // ... }
_POSIX_VERSION
检测是否支持 MSG_NOSIGNAL
,从而在更多平台上添加了对 MSG_NOSIGNAL
的支持。executor
概念,以测试 const 限定的 execute()
。any_executor
的支持。thread_pool
单元测试。asio::query
引起的阴影名称警告。push/pop_options.hpp
包含。select
反应器。any_executor
比较和转换引起的潜在歧义。strand<>
在以较旧的 C++ 版本或不太符合标准的编译器为目标时对 Networking TS 执行器的适配。io_context::executor_type
、thread_pool::executor_type
、system_executor
和 strand
执行器现在满足提议的标准执行器的要求。这些类还继续满足现有网络 TS 执行器模型的要求。dispatch
、post
、defer
、get_associated_executor
、bind_executor
、make_work_guard
、spawn
、co_spawn
、async_compose
、use_future
等,都可以与新的提议的标准执行器以及现有的网络 TS 执行器互操作。实现会在编译时确定特定执行器满足哪个模型;如果检测到两者,则优先使用提议的标准执行器模型。any_io_executor
类型别名已作为所有 I/O 对象的新默认运行时多态执行器引入。此类型别名指向 execution::any_executor<>
模板,其中指定了一组可支持的属性以用于 I/O。此更改可能会破坏直接使用旧多态包装器 executor
的现有代码。如果向后兼容性是必需的,则可以定义 BOOST_ASIO_USE_TS_EXECUTOR_AS_DEFAULT
,这将更改 any_io_executor
类型别名以改为指向 executor
多态包装器。BOOST_ASIO_NO_TS_EXECUTORS
来禁用对现有网络 TS 执行器模型的支持。为 basic_waitable_timer
添加了转换移动构造和赋值。这启用了不同计时器类型之间的移动构造和赋值,前提是执行器类型是可转换的。例如
basic_waitable_timer< clock_type, traits_type, io_context::executor_type > timer1(my_io_context); basic_waitable_timer< clock_type, traits_type, any_io_executor // polymorphic wrapper > timer2(std::move(timer1));
gcc
10 时启用了 C++20 协程支持。添加了 co_spawn
的重载,用于启动可等待对象。此更改允许我们编写
co_spawn(executor, echo(std::move(socket)), detached);
而不是
co_spawn(executor, [socket = std::move(socket)]() mutable { return echo(std::move(socket)); }, detached);
use_awaitable_t
的默认执行器适配器添加了新的构造函数重载,以启用执行器类型之间的转换。as_default_on()
和 as_default_on_t<>
,添加了对使用 detached_t
作为默认完成令牌的支持。ssl::stream<>
添加了移动构造函数。ssl::stream<>
写入操作以线性化收集写入缓冲区序列。asio_handler_invoke
挂钩的编译时检测。此挂钩已随着网络 TS 特性 associated_executor
和函数 get_associated_executor()
的引入而被弃用。如果任何处理程序实现 asio_handler_invoke
挂钩,则使用 BOOST_ASIO_NO_DEPRECATED
编译应用程序现在将触发编译错误。asio_handler_allocate
和 asio_handler_deallocate
钩子的编译时检测。这些钩子在引入 Networking TS 特性 associated_allocator
和函数 get_associated_allocator()
时已被弃用。如果任何处理程序实现了 asio_handler_allocate
或 asio_handler_deallocate
钩子,则使用 BOOST_ASIO_NO_DEPRECATED
编译应用程序现在将触发编译错误。recv
而不是 recvmsg
,send
而不是 sendmsg
,read
而不是 readv
,以及 write
而不是 writev
。executor
的引用计数开销。errno
和错误代码。io_context::exeutor_type
),则应用额外的优化。为处理程序跟踪添加了源位置支持。新的 BOOST_ASIO_HANDLER_LOCATION((file_name, line, function_name))
宏可用于通知处理程序跟踪机制源位置。此宏声明一个放置在堆栈上的对象。然后,当使用位置信息启动异步操作时,它会在表示异步操作开始的 n*m
行之前,使用 <action> n^m
输出行。例如
@asio|1589423304.861944|>7|ec=system:0,bytes_transferred=5
@asio|1589423304.861952|7^8|in 'async_write' (...../../include/asio/impl/write.hpp:330)
@asio|1589423304.861952|7^8|called from 'do_write' (handler_tracking/async_tcp_echo_server.cpp:62)
@asio|1589423304.861952|7^8|called from 'operator()' (handler_tracking/async_tcp_echo_server.cpp:51)
@asio|1589423304.861952|7*8|socket@0x7ff61c008230.async_send
@asio|1589423304.861975|.8|non_blocking_send,ec=system:0,bytes_transferred=5
@asio|1589423304.861980|<7|
如果 std::source_location
或 std::experimental::source_location
可用,则 use_awaitable_t
令牌(当默认构造或用作默认完成令牌时)也将导致处理程序跟踪为每个新创建的异步操作输出源位置。use_awaitable_t
对象也可以使用位置信息显式构造。
handlerviz.pl
工具进行了各种改进。添加了 handlerlive.pl
工具,该工具处理处理程序跟踪输出以生成“活动”处理程序的列表。活动处理程序是那些与待处理异步操作关联的处理程序,以及当前正在执行的处理程序。例如
cat output.txt | perl handlerlive.pl
或者
perl handerlive.pl < output.txt
或者
perl handlerlive.pl output.txt
添加了 handlertree.pl
工具,该工具过滤处理程序跟踪输出,以仅包括树中生成指定处理程序的那些事件。例如,要过滤输出以仅包括与处理程序 123
、456
及其前身关联的事件
cat output.txt | perl handlertree.pl 123 456
或者
perl handlertree.pl 123 456 < output.txt
此脚本可以与 handerlive.pl 和 handlerviz.pl 结合使用,以生成“活动”异步操作链的图表。例如
cat output.txt | \
perl handlertree.pl perl handlerlive.pl output.txt
| \
perl handlerviz.pl | \
dot -Tsvg > output.svg
async_compose
以在使用左值传递时与可复制处理程序一起工作。co_spawn
中的完成签名推导。executor_binder
实现中删除了伪造的 Executor
基类。noexcept
。ssl::host_name_verification
类,它是 ssl::rfc2818_verification
的直接替代品。ssl::rfc2818_verification
类已被标记为已弃用。由于此更改,SSL 支持现在依赖于 OpenSSL 1.0.2 中引入的函数。ssl::context
构造函数以获取本机句柄的所有权。gcc
的 C++ 语言版本检测,以使用 __cplusplus
宏。strand<>
转换构造函数和赋值运算符。async_read
重载中伪造的处理程序需求检查。ssl::context
类以从 add_certificate_authority
函数传播非 EOF 错误。thread_pool
析构函数挂起。select
reactor 以在错误时重新创建“自管道技巧”套接字。这解决了 Windows 某些版本上的一个问题,在系统睡眠后,这些套接字会断开连接。priority_scheduler
示例以演示对 shutdown()
和 destroy()
的调用。use_awaitable_t::as_default_on
函数中的编译错误。boost::placeholders
命名空间。async_compose
实现中发生的潜在编译错误。async_initiate
辅助函数以自动推断其返回类型。这对于 C++11 或更高版本启用。return_type
。async_initiate
。completion_signature<T>
:检查 T
是否为 R(Args...)
形式的签名。completion_handler_for<T, Signature>
:检查 T
是否可用作具有指定签名的完成处理程序。completion_token_for<T, Signature>
:检查 T
是否是可以与 async_initiate 和指定签名一起使用的完成令牌。BOOST_ASIO_COMPLETION_SIGNATURE
、BOOST_ASIO_COMPLETION_HANDLER_FOR
和 BOOST_ASIO_COMPLETION_TOKEN_FOR
。当不支持概念时,这些宏会扩展为 typename
。将嵌套模板类型 rebind_executor
添加到所有 I/O 对象类型,作为将其通用地重新绑定以使用替代 I/O 执行器的方法。例如
using my_socket_type = tcp::socket::rebind_executor<my_executor_type>::other;
executor_type
和成员函数 get_executor()
报告其关联的 I/O 执行器。请注意,executor_type
和 get_executor()
的存在应视为可选,因此,最好通过 associated_executor
特征和 get_associated_executor()
辅助函数来访问它们。添加了 default_completion_token
特征,以便每个 I/O 执行器类型现在都具有关联的默认完成令牌类型。此特征可以在异步操作声明中使用,如下所示
template < typename IoObject, typename CompletionToken = typename default_completion_token< typename IoObject::executor_type >::type > auto async_fyz( IoObject& io_object, CompletionToken&& token = typename default_completion_token< typename IoObject::executor_type >::type{} );
如果未特化,则此特征类型为 void
,这意味着给定 I/O 执行器没有可用的默认完成令牌类型。
为 use_awaitable
完成令牌特化了 default_completion_token
特征,以便可以按以下示例所示使用它
auto socket = use_awaitable.as_default_on(tcp::socket(my_context)); // ... co_await socket.async_connect(my_endpoint); // Defaults to use_awaitable.
在此示例中,socket
对象的类型从 tcp::socket
转换为具有默认完成令牌设置为 use_awaitable
的 I/O 执行器。或者,可以直接计算套接字类型
using tcp_socket = use_awaitable_t<>::as_default_on_t<tcp::socket>; tcp_socket socket(my_context); // ... co_await socket.async_connect(my_endpoint); // Defaults to use_awaitable.
async_initiate
添加到 Windows 特定的 I/O 对象的异步操作。确保执行器类型传播到新接受的套接字。当同步或异步接受新连接,但在未指定执行器或执行上下文的情况下,接受操作现在将正确地将执行器类型从 acceptor 传播到 socket。例如,如果您的 acceptor 类型是
basic_socket_acceptor<ip::tcp, my_executor_type>
那么您接受的套接字类型将是
basic_stream_socket<ip::tcp, my_executor_type>
Protocol
复制和移动操作永远不会抛出异常。Endpoint
默认构造函数和移动操作永远不会抛出异常。noexcept
限定符添加到协议访问器。noexcept
限定符添加到套接字移动构造函数。connect()
实现中的 case
直通,消除了编译器警告。is_*_buffer_sequence
检测特征。CancelIoEx
入口点时,不兼容指针转换的警告。get_option()
成员函数为 const。shutdown
函数的名称隐藏问题。is_dynamic_buffer
的文档应用了小小的修复。Executor
模板参数。此模板参数默认为 asio::executor
类型(多态执行器包装器),但可用于指定用户定义的执行器类型。asio::io_context&
的 I/O 对象的构造函数和函数现在接受 Executor
或对具体 ExecutionContext
(例如 asio::io_context
或 asio::thread_pool
)的引用。注意:现有用户代码中一个潜在的破坏来源是在重用 I/O 对象的 io_context
来构造另一个 I/O 对象时,例如
asio::steady_timer my_timer(my_socket.get_executor().context());
要修复此问题,请使用第一个 I/O 对象的执行器构造第二个 I/O 对象
asio::steady_timer my_timer(my_socket.get_executor());
或者以其他方式显式传递 io_context
asio::steady_timer my_timer(my_io_context);
get_io_context
和 get_io_service
成员函数现已删除。async_result
形式,带有 initiate
静态成员函数。async_result
模板现在支持新形式
template <typename CompletionToken, typename Signature> struct async_result { typedef /* ... */ return_type; template <typename Initiation, typename RawCompletionToken, typename... Args> static return_type initiate( Initiation&& initiation, RawCompletionToken&& token, Args&&... args); };
initiate
成员函数必须:(a)将令牌转换为完成处理程序对象 handler
;(b)导致函数对象 initiation
的调用,就像通过调用 std::forward<Initiation>(initiation)(std::move(handler), std::forward<Args>(args)...)
。请注意,initiation
的调用可能会被延迟(例如,延迟评估),在这种情况下,initiation
和 args
必须按需进行衰减复制和移动。async_initiate
,作为调用 async_result<>::initiate
的包装器。为了向后兼容,此函数同时支持旧的和新的 async_result
形式。async_initiate
。handler_type
特征和 async_result
的单参数形式现已删除。asio
命名空间。awaitable<>
、co_spawn
、this_coro
、detached
和 redirect_error
工具已从 asio::experimental
命名空间移动到命名空间 asio
。作为此更改的一部分,this_coro::token()
awaitable 已被 asio::use_awaitable
完成令牌取代。use_awaitable
和 redirect_error
完成令牌仅适用于使用带有成员函数 initiate
的新形式 async_result
的异步操作。此外,当使用 use_awaitable
时,请注意,异步操作在 co_await
应用于 awaitable<>
之前不会启动。DynamicBuffer_v2
概念,它是 CopyConstructible 的。此更改为动态缓冲区添加了一组新的类型要求 DynamicBuffer_v2
,它支持复制构造。这些新的类型要求使动态缓冲区可以用作用户定义的组合操作的参数,在这些操作中,相同的动态缓冲区对象被重复用于多个底层操作。例如
template <typename DynamicBuffer> void echo_line(tcp::socket& sock, DynamicBuffer buf) { n = asio::read_until(sock, buf, '\n'); asio::write(sock, buf, asio::transfer_exactly(n)); }
DynamicBuffer
类型要求已重命名为 DynamicBuffer_v1
。这些要求继续与 Networking TS 兼容。is_dynamic_buffer_v1
和 is_dynamic_buffer_v2
,分别用于测试是否符合 DynamicBuffer_v1
和 DynamicBuffer_v2
。is_dynamic_buffer
的现有特征已保留,并委托给 is_dynamic_buffer_v1
(除非显式定义了 BOOST_ASIO_NO_DYNAMIC_BUFFER_V1
,在这种情况下,它委托给 is_dynamic_buffer_v2
)。dynamic_string_buffer
和 dynamic_vector_buffer
类都符合 DynamicBuffer_v1
和 DynamicBuffer_v2
要求。BOOST_ASIO_NO_DYNAMIC_BUFFER_V1
时,对 DynamicBuffer_v1
类型和函数的所有支持都使用 #ifdef-ed 排除。因此,也禁用了将 basic_streambuf
与 read
、async_read
、read_until
、async_read_until
、write
和 async_write
函数一起使用的支持。async_compose
函数,该函数简化了用户定义的异步操作的实现。make_strand
函数,该函数创建具有推导出的 Executor
模板参数的 strand
。local::basic_endpoint
添加了采用 string_view
的构造函数。ip::address
、ip::address_v4
、ip::address_v6
、ip::basic_endpoint
和 executor_work_guard
类的各种成员函数。buffer_sequence_begin
和 buffer_sequence_end
函数。BOOST_ASIO_DISABLE_VISIBILITY
配置 #define
,允许禁用可见性编译指示。(注意:如果符号被隐藏,则必须格外小心以确保 Asio 类型不会跨共享库 API 边界传递。)error::message_size
)时返回已传输的正确字节数。reuse_address
选项时自动应用 SO_REUSEPORT
,修复了 QNX 上的多播行为。unistd.h
,以修复功能检测。network_v[46].hpp
标头添加到顶层便利标头。pthread_cond_timedwait
时绝对超时时间的计算。EndpointSequence
迭代器类型,而不是假定存在 const_iterator
typedef。buffer_sequence_begin
和 buffer_sequence_end
以防止隐式转换。此更改解决了以下问题:调用 buffer_sequence_begin
或 buffer_sequence_end
可能会触发到 const_buffer
或 mutable_buffer
的隐式转换。每当发生此隐式转换时,buffer_sequence_begin
或 buffer_sequence_end
的返回值将指向临时对象。eof
错误,因为它实际上表示成功。SSL_ERROR_SYSCALL
结果但没有关联错误的情况添加了回退错误代码。<atomic>
,即使对于 C++03 也是如此。这修复了关于 OSMemoryBarrier
弃用的警告。decltype
支持。_WIN32_WINNT
的默认值增加到 0x0601
(Windows 7)。dispatch
文档,以注意它可能会在当前线程中调用提供的函数对象。post
和 defer
文档,以阐明它们之间的区别。system_executor
关联的执行上下文在退出时未正确清理的 Windows 特定的问题。std::future
可用性检测的问题。read_until
的 regex 重载中的编译错误。std::experimental::string_view
和 std::string_view
的问题。std::invoke_result
可用性的 MSVC 版本检测。decltype
可用时测试新要求。size()
、max_size()
或 empty()
时发生的崩溃。std::string_view
检测问题。io_context::executor_type::dispatch
的处理程序跟踪操作名称。basic_socket_acceptor::get_option
添加了缺少的 const 限定符。experimental::detached
完成令牌。experimental::redirect_error
完成令牌。experimental::co_spawn
功能。asio::steady_timer
而不是 asio::deadline_timer
。asio::dynamic_buffer
而不是 asio::streambuf
。asio::io_context::run_for()
函数。BOOST_ASIO_NO_DEPRECATED
时单元测试编译失败的问题。BOOST_ASIO_USE_BOOST_DATE_TIME_FOR_SOCKET_IOSTREAM
以在 basic_socket_streambuf
和 basic_socket_iostream
中启用旧的 Boost.Date_Time 接口。is_dynamic_buffer
特性中的不正确的成员函数检测器。async_result
与已弃用的 handler_type
的不兼容性。basic_resolver_results::value_type
typedef。SSL_OP_NO_COMPRESSION
时某些 OpenSSL 版本上的编译错误。add_certificate_authority
以处理捆绑包中的多个证书。std::invoke_result
而不是 std::result_of
,消除了 MSVC 的弃用警告。std::string_view
,为 C++14 使用 std::experimental::string_view
。定义预处理器宏 BOOST_ASIO_DISABLE_STD_STRING_VIEW
以强制在 C++17 模式下编译时使用 std::experimental::string_view(假设可用)。enable_if
测试中使用之前,DynamicBuffer
模板参数已衰减。basic_yield_context
以使其能够与包含引用参数的完成签名一起工作。spawn()
启动的堆栈协程正确存储其函数和处理程序参数的衰减副本。basic_socket<Protocol>
,而不是 basic_socket<Protocol, SocketService>
。可以通过定义 BOOST_ASIO_ENABLE_OLD_SERVICES
宏来启用旧接口。io_context
基础上禁用锁定。ssl::stream<>
构造函数参数启用了完美转发。g++
版本 >= 4.7 才能使用标准原子操作,以修复使用 g++
4.6 时的链接器错误 (#13121)。constexpr
和可变参数模板的使用。auto_ptr
的使用。async_accept
实现中 asio_handler_is_continuation
结果的错位使用。poll.h
而不是 sys/poll.h
(#12419)。__thread
关键字扩展的使用。EAGAIN
或 EWOULDBLOCK
而失败)与 posix::stream_descriptor
一起使用添加了有限的支持。allocator_traits
来重新绑定分配器。ssl::context_base
枚举,以支持任何 TLS 版本,并提高了跨 OpenSSL 版本的 SSL/TLS 版本处理的一致性。gcc
发出的一些虚假的未使用变量警告 (#12302)。std::atomic_thread_fence
(如果可用),以消除最新的 macOS SDK 上的已弃用函数警告 (#12482)。getaddrinfo
添加了一个解决方法。connect_condition
返回结束迭代器时 asio::connect()
中的越界迭代器使用问题 (#12354)。getsockname
报告 0.0.0.0 时才绑定到 127.0.0.1 (#12406)。SSL_COMP_free_compression_methods
的调用,以修复在关闭时报告的两个内存泄漏问题,适用于 OpenSSL 版本 >= 1.0.2 和 < 1.1.0 (#10795)。std::allocator<void>
的使用更改为非 void 模板参数,修复了在某些标准库实现上遇到的 use_future
编译错误。getaddrinfo
的使用,而不是根据 getipnodebyname
的模拟。OPENSSL_NO_SSL3
功能测试 #define
(#11754)。SSL_CTX_clear_chain_certs
函数(如果可用)。getaddrinfo
模拟和 SSL 包装器的密码处理中传递给 strncat
的缓冲区大小。CreateEventW
而不是 CreateEvent
(#11732)。ConnectEx
函数生成的错误映射到其可移植的等效项 (#10744)。BOOST_ASIO_DISABLE_CONNECTEX
,以允许显式禁用 ConnectEx
的使用。windows::object_handle
在销毁时有挂起的等待操作时的竞争条件 (#10624)。EINVAL
。ssl::stream<>
错误。ERR_remove_state
的使用。g++
检测 C++11 std::addressof
的问题 (#10982)。join_group
失败视为非致命错误。std::endl
,以确保输出被刷新。yield_context
对象时,添加了对仅移动返回类型的支持。yield_context
以允许从启动函数对完成处理程序进行可重入调用。kqueue
reactor,使其可以在 FreeBSD 上工作 (#10606)。kqueue
reactor 中的一个问题,该问题导致在 Mac OS 上使用串口时发生旋转 (#10496)。kqueue
reactor 对只读文件描述符的支持 (#10367)。/dev/poll
reactor 时的编译错误 (#10350, #10572)。WSASocketW
,因为 WSASocketA
已被弃用 (#10534)。asio.hpp
便利头文件时,use_future
和 spawn()
不可用 (#10567)。asio::strand
为已弃用。请改用 asio::io_service::strand
。kqueue
后端中的回归。gcc
构建单元测试添加了一个解决方法。gcc
问题 (#10042)。HANDLE
后端更改以忽略 ERROR_MORE_DATA
。相反,错误将像任何其他错误一样传播(即在 error_code
中或作为 system_error
抛出),并将返回传输的字节数。对于需要处理部分消息的代码,应使用 error_code
重载 (#10034)。signal_set
实现的信号编号检查中的差一错误 (#9324)。SO_UPDATE_CONNECT_CONTEXT
(#10016)。VerifyVersionInfo
而不是 GetVersionEx
,因为 GetVersionEx
已被弃用。asio::spawn()
以使其与新的 Boost.Coroutine 接口正确工作 (#9442, #9928)。asio::spawn()
协程在被 io_service
析构函数清理时被正确地展开 (#9731)。io_service::wrap()
和 strand::wrap()
生成的处理程序的延续钩子的委托 (#9741)。ConnectEx
(如果可用)。io_service
后端,以便每个 io_service
实例使用单个条件变量。这解决了从多个线程使用 run_one()
时可能发生的竞争条件。boost::chrono
和 std::chrono
时钟计算超时时发生整数溢出 (#9662, #9778)。EV_CLEAR
处理进行了进一步更改,以解决 close()
系统调用可能在 Mac OS X 上挂起的其他情况。resolver_query_base::flags::operator~
实现中的无限递归 (#9548)。select
reactor 更加高效 (#9528)。gcc
报告的 Windows 特定类型别名问题 (#9550)。GetQueuedCompletionStatus
超时解决方法。io_service
、strand
、缓冲区、组合操作、定时器等)都应正常工作。cancel()
函数。异步操作只能通过关闭套接字来取消。null_buffers
的操作。tcp::no_delay
和 socket_base::keep_alive
选项。async_connect
中的错误未正确传播到完成处理程序的回归问题 (#8795)。io_service
时发生的 Windows 特定回归问题(在 Boost 1.54 中引入)。当错误发生时,异步操作的结果(错误和传输的字节数)会被错误地丢弃,并使用零值代替。对于 TCP 套接字,这会导致虚假的 end-of-file 通知 (#8933)。async_wait
时,信号编号被正确传递给完成处理程序 (#8738)。async_write_at
操作 (#8669)。HANDLE
后端,以便在 GetOverlappedResult
为同步读取返回 ERROR_MORE_DATA
时,将其视为非致命错误 (#8722)。generic
作为关键字。添加了一个解决方法,当这些语言扩展生效时,将命名空间重命名为 cpp_generic
。async_result
支持的机会。特别是,缓冲流模板已更新,以便它们遵守当前的处理程序模式 (#9000, #9001)。use_future
支持。std::min
的使用,以避免依赖 <algorithm>
头文件 (#8758)。SSL_CTX_clear_options
函数的旧版本 OpenSSL 的支持 (#9273)。handler_type
和 async_result
,允许自定义启动函数的返回类型。asio::spawn()
函数,这是一个用于运行基于 Boost.Coroutine 库的有栈协程的高级包装器。spawn()
函数使程序能够以同步方式实现异步逻辑。例如:size_t n = my_socket.async_read_some(my_buffer, yield);
。有关更多信息,请参阅有栈协程。asio::use_future
特殊值,它为从异步操作的启动函数返回 C++11 std::future
提供了第一流的支持。例如:future<size_t> = my_socket.async_read_some(my_buffer, asio::use_future);
。更多信息,请参阅 Futures(Future)。asio_handler_is_continuation
的新处理程序钩子。异步操作可能表示与当前执行处理程序关联的异步控制流的延续。asio_handler_is_continuation
钩子可以自定义为在满足条件时返回 true
,并且 Asio 的实现可以使用此知识来优化新处理程序的调度。为了涵盖常见情况,Asio 为 strands、spawn()
和组合异步操作自定义了此钩子。generic::datagram_protocol
、generic::raw_protocol
、generic::seq_packet_protocol
和 generic::stream_protocol
,它们实现了 Protocol
类型要求,但允许用户在运行时指定地址族(例如 AF_INET
)和协议类型(例如 IPPROTO_TCP
)。更多信息,请参阅 对其他协议的支持。ip::tcp::socket
可以通过移动构造转换为 generic::stream_protocol::socket
。更多信息,请参阅 对其他协议的支持。basic_socket_acceptor<>
的 accept()
和 async_accept()
函数,以允许将新连接直接接受到更通用类型的套接字中。例如,ip::tcp::acceptor
可以用于接受到 generic::stream_protocol::socket
对象中。更多信息,请参阅 对其他协议的支持。ssl::stream<>
类的 handshake()
和 async_handshake()
函数的新重载。这些重载接受一个 ConstBufferSequence
,用作握手过程的 ssl 引擎的初始输入。ssl::context
对象 的支持。ssl::context
和 ssl::stream<>
类添加了 set_verify_depth()
函数。add_certificate_authority()
、use_certificate()
、use_certificate_chain()
、use_private_key()
、use_rsa_private_key()
和 use_tmp_dh()
已添加到 ssl::context
类中。ssl::context
以默认自动禁用 SSL 压缩。要启用,请使用新的 ssl::context::clear_options()
函数,如 my_context.clear_options(ssl::context::no_compression)
中所示。signal_set
实现中潜在的死锁。#warning
指令 #7939。epoll
实现中潜在的数据竞争。NULL
)error_category
的 error_code
#8613。basic_waitable_timer
的底层实现,使其可以处理任何 time_point
值,而不会使中间 duration 对象溢出。io_service
对象上并发调用 run()
和 poll()
时可能发生的线程唤醒丢失问题 #8354。ssl::rfc2818_verification
类中的内存泄漏。boost/asio/detail/winsock_init.hpp
。basic_socket::get_option
文档中嵌入的示例中的错误 (#7562)。long
而不是 int
作为 SSL_CTX 选项,以匹配 OpenSSL (#7209)。_snwprintf
以解决由于最近版本的 MinGW 中 swprintf
签名更改而导致的编译错误 (#7373)。io_service
线程池时可能在 Windows 上发生的死锁 (#7552)。noexcept
限定符 (#7797)。accept
的错误视为非致命错误 (#7488)。ip::tcp::iostream
和 C++11 之间的不兼容性 (#7162)。#include <cctype>
,某些 MinGW 版本需要它。gcc
的原子内置函数 (#7140)。io_service
被销毁后销毁。epoll_create1()
函数,但总是以 ENOSYS
失败 (#7012)。buffered_write_stream
中的另一个回归问题 (#6310)。epoll_reactor
后端,对 EPOLLOUT
事件执行延迟注册。epoll_reactor
对带外数据的处理,该处理在前一个版本中的不完整修复中被破坏。OPENSSL_NO_ENGINE
功能测试 #define
(#6432)。windows::object_handle
,使其可以在支持 C++11 移动语义的 Windows 编译器(例如 g++
)下工作。g++
4.7 的支持 (#6620)。io_service
使用 1 的 concurrency_hint
构建时,signal_set
处理程序未被传递的问题 (#6657)。basic_waitable_timer
,它基于 C++11 时钟类型要求。它可以与 C++11 <chrono>
库工具中的时钟一起使用,或者在这些时钟不可用时,与 Boost.Chrono 一起使用。类型别名 high_resolution_timer
、steady_timer
和 system_timer
可以用于为标准时钟类型创建定时器对象。windows::object_handle
类,用于对 Windows 内核对象执行等待操作。感谢 Boris Schaeling 为此功能的开发做出了重大贡献。connect()
在某些情况下可以返回 EAGAIN。已将其重新映射到另一个错误,使其看起来不像非阻塞操作 (#6048)。buffered_write_stream
中的一个回归问题 (#6310)。io_service
而没有任何操作时发生的非分页池“泄漏” (#6321)。concurrency_hint
为 1 时)中使用线程本地操作队列,以消除锁/解锁对。epoll_reactor
推测性操作。epoll_reactor
的 I/O 操作来提高引用局部性。当多个线程运行 io_service
时,这也提高了跨 CPU 的可扩展性。boost::array
或 std::array
)的缓冲区序列专门化了异步读取和写入操作。async_read_until
的 regex 重载中的编译错误 (#5688)。signal()
函数,修复了 Windows 特定的编译错误 (#5722)。deadline_timer
的实现,使其仅在定时器堆非空时才读取时钟。null_buffers
操作的行为,使其服从用户的非阻塞设置 (#5756)。fd_set
的大小。epoll_reactor
初始化中的异常安全问题 (#6006)。BOOST_ASIO_STRAND_IMPLEMENTATIONS
定义为所需的数量,使 strand 实现的数量可配置。BOOST_ASIO_ENABLE_SEQUENTIAL_STRAND_ALLOCATION
标志的支持,该标志切换 strand 实现的分配以使用轮询方法而不是哈希。strand.post()
时可能发生的潜在 strand 饥饿问题。signal_set
的新类。程序可以向集合添加一个或多个信号,然后执行 async_wait()
操作。当其中一个信号发生时,将调用指定的处理程序。同一个信号编号可以注册到多个 signal_set
对象,但是,该信号编号必须仅与 Asio 一起使用。地址 #2879。BOOST_ASIO_ENABLE_HANDLER_TRACKING
启用时,Asio 会将调试输出写入标准错误流。输出记录异步操作及其处理程序之间的关系。可以使用包含的 handlerviz.pl
工具对输出进行后处理,以创建处理程序的可视化表示(需要 GraphViz)。ip::tcp::iostream
。通过调用 expires_at()
或 expires_from_now()
设置超时以建立截止时间。任何发生在截止时间之后的套接字操作都会使 iostream 进入错误状态。error()
成员函数,用于检索最近一次系统调用的错误代码。basic_deadline_timer::cancel_one()
函数。此函数允许您取消定时器上的单个等待处理程序。处理程序按 FIFO 顺序取消。transfer_exactly()
完成条件。即使缓冲区(或缓冲区序列)的总大小较大,也可以使用它来发送或接收指定数量的字节。connect()
和 async_connect()
。这些操作会尝试列表中的每个端点,直到套接字成功连接,并且对于创建同时适用于 IPv4 和 IPv6 的 TCP 客户端非常有用。buffer_size()
函数,使其除了单个缓冲区之外,还可以用于缓冲区序列。buffer_copy()
函数,该函数可用于在单个缓冲区和缓冲区序列之间复制原始字节。read()
、read_at()
、write()
和 write_at()
,它们不需要完成条件。g++
4.5 或更高版本,以及 MSVC 10),static_assert
也用于生成信息丰富的错误消息。可以通过定义 BOOST_ASIO_DISABLE_HANDLER_TYPE_REQUIREMENTS
来禁用此检查。BOOST_ASIO_ENABLE_OLD_SSL
来使用旧的实现。地址 #3702, #3958。boost/asio/ssl/impl/src.hpp
。is_loopback()
、is_unspecified()
和 is_multicast()
函数在 ip::address
、ip::address_v4
和 ip::address_v6
类中保持一致可用性 (#3939)。non_blocking()
函数。名为 non_blocking_io
的 io_control()
命令现在已被弃用,而推荐使用这些新函数。native_non_blocking()
函数。这些函数旨在允许将任意非阻塞系统调用封装为异步操作,这种方式对于套接字对象的用户来说是透明的。这些函数对套接字或描述符的同步操作的行为没有影响。io_control()
成员函数 (#3297)。release()
成员函数。此函数将底层本机描述符的所有权释放给调用者。地址 #3900。SOCK_SEQPACKET
) 的支持。io_service::stopped()
函数,该函数可用于确定 io_service
是否已停止(即,在进一步调用 run()
、run_one()
、poll()
或 poll_one()
之前需要调用 reset()
)。native_type
类型别名,而推荐使用 native_handle_type
,并弃用了 native()
成员函数,而推荐使用 native_handle()
。fork()
系统调用的支持。使用 fork()
的程序必须在适当的时间调用 io_service.notify_fork()
。添加了两个新示例,展示如何使用此功能。地址 #3238, #4162。close()
系统调用报告的错误的处理。特别是,假设大多数操作系统不会因 close()
因 EWOULDBLOCK
错误而失败,但如果发生这种情况,则设置阻塞模式并重新启动调用。如果发生任何其他错误,则假定描述符已关闭。地址 #3307。asio::buffer()
重载,用于 std::array
(如果可用)。array
、shared_ptr
、weak_ptr
和 atomic
可用时使用它们,而不是使用 Boost 等效项。what()
消息中包含函数名称。shutdown_service()
成员函数更改为私有。ip::basic_endpoint<>
对象(例如 ip::tcp::endpoint
和 ip::udp::endpoint
)的大小。assign()
添加的任何描述符或套接字都可能已被 dup()
,因此需要从 reactor 显式注销 (#4971)。io_service()
的成员函数。应改为使用 get_io_service()
成员函数。ip::tcp
、ip::udp
和 ip::icmp
类中删除了已弃用的 typedef resolver_query
和 resolver_iterator
。buffers_iterator<>
和 ip::basic_resolver_iterator
类,以便 value_type typedef 是非 const 字节类型。-Wshadow
编译器选项报告的警告 (#3905)。FIONBIO
常量转换为 int,以抑制某些平台上的编译器警告 (#5128)。tick_count_timer
示例中的错误,方法是将持续时间类型设为有符号类型。以前,等待已过期的截止时间不会在很长时间内返回 (#5418)。EV_ONESHOT
似乎在某些版本的 Mac OS X 上引起问题,io_service
析构函数在 close()
系统调用中陷入停滞。将 kqueue 后端更改为使用 EV_CLEAR
代替 (#5021)。g++
编译失败的问题 (#4883)。EWOULDBLOCK
而失败的系统调用未正确地重新注册到 kqueue。asio::streambuf
,以确保在使用 std::streambuf
成员函数修改数据后,其内部指针已正确更新。ip::address_v4::broadcast()
时发生的整数溢出问题。io_service
,则 deadline_timer
可能永远不会触发 (#4568)。has_service<>
的有效使用进行编译 (#4638)。close()
/closesocket()
失败已正确传播 (#4573)。InitializeCriticalSectionAndSpinCount
返回的错误的检查 (#4574)。pselect()
(#4578)。deadline_timer
对象可能永远不会过期 (#4745)。resolver
后端,以便空服务名称解析为端口号 0
,如文档所述 (#4690)。const_buffers_1
的缓冲区序列 (#4746)。Protocol
和 id
,以避免与 Objective-C++ 关键字冲突 (#4191)。deadline_timer
对象时可能发生的 vector
重新分配性能问题 (#4780)。io_control()
实现 (#4782)。accept()
的失败被错误地视为成功 (#4859)。<boost/asio/impl/src.cpp>
,而推荐使用 <boost/asio/impl/src.hpp>
(#4560)。#include
,例如,如果程序使用 boost::array
但未显式包含 <boost/array.hpp>
。)deadline_timer
实现以提高性能。asio::streambuf
与 async_read()
和 async_read_until()
的性能。这些读取操作现在在读取时使用 streambuf
的现有容量,而不是将读取限制为 512 字节。#include <boost/asio/impl/src.cpp>
添加到程序中的一个源文件,然后在项目/编译器设置中定义 BOOST_ASIO_SEPARATE_COMPILATION
来构建程序。或者,可以定义 BOOST_ASIO_DYN_LINK
以构建作为共享库一部分的单独编译的 Asio。BOOST_ASIO_DISABLE_FENCED_BLOCK
,以允许禁用完成处理程序周围的内存栅栏,即使启用了线程支持。const
类型传递。async_send_to
的 null_buffers
变体中不正确的参数顺序 (#4170)。getaddrinfo
仿真中使用 unsigned char
与 isdigit
(#4201)。buffers_iterator
中添加了缺少的 operator+
重载 (#4382)。null_buffers
操作的取消。timerfd
来调度计时器(如果可用)。ip::resolver_query_base::flags
。此类型阻止从 int
到 flags
的隐式转换,从而允许编译器捕获用户错误地将数字端口号作为服务名称传递的情况。#define NOMINMAX
。用户可以定义 BOOST_ASIO_NO_NOMINMAX
来抑制此定义 (#3901)。error::eof
结果传递给完成处理程序 (#4023)。io_control()
成员函数,以便在修改阻塞模式时始终在底层描述符上调用 ioctl
(#3307)。InternetProtocol::resolver_query
和 InternetProtocol::resolver_iterator
,因为这两个 typedef 都不是文档化的 InternetProtocol
要求的一部分。ip::tcp
、ip::udp
和 ip::icmp
类中相应的 typedef 已被弃用。select()
的 reactor 的带外处理。BOOST_ASIO_DISABLE_THREADS
宏,允许独立禁用 Asio 的线程支持。boost::addressof
获取处理程序对象的地址,而不是直接应用 operator&
(#2977)。OVERLAPPED
结构保持有效,直到启动函数调用返回并且完成数据包已传递。extern "C"
线程入口点函数添加了 boost_
前缀 (#3809)。getaddrinfo
仿真中,仅当指定了服务名称时才检查套接字类型(SOCK_STREAM
或 SOCK_DGRAM
)。这应该允许仿真与原始套接字一起使用。buffered*_stream<>
模板,将 0 字节的读取和写入操作视为无操作,以符合 SyncReadStream
、AsyncReadStream
、SyncWriteStream
和 AsyncWriteStream
的文档类型要求。throw
关键字的一些实例更改为 boost::throw_exception()
,以允许在禁用异常支持时使用 Asio。请注意,SSL 包装器仍然需要异常支持 (#2754)。/dev/poll
后端中的冗余系统调用。_GLIBCXX_DEBUG
时报告的失败 (#3098)。BOOST_ASIO_HASH_MAP_BUCKETS
来调整 bucket 数组使用的大小。(注意:此功能引入了一个 bug,该 bug 在 Asio 1.4.3 / Boost 1.40 中已修复。)io_control()
的实现,使其符合 IoControlCommand 的文档类型要求 (#2820)。ReadFile
调用因 ERROR_MORE_DATA
而失败的情况。这启用了一个 hack,其中 windows::stream_handle
可以与面向消息的命名管道一起使用 (#2936)。BOOST_ASIO_DISABLE_SERIAL_PORT
,则不要包含 termios.h (#2917)。size_t CompletionCondition(error_code ec, size_t total)
增强了 CompletionCondition 概念,其中返回值指示下次读取或写入操作要传输的最大字节数。(旧的 CompletionCondition 签名仍然支持向后兼容性)。HANDLE
(例如命名管道)的包装器(需要与 I/O 完成端口一起使用的 HANDLE
)。HANDLE
(例如文件)的包装器(需要与 I/O 完成端口一起使用的 HANDLE
)。null_buffers
类型添加了对 reactor 样式操作(即,它们报告就绪状态但不执行 I/O)的支持。read_until()
和 async_read_until()
重载,它们采用用户定义的函数对象来定位消息边界。BOOST_ASIO_ENABLE_TWO_LOCK_QUEUE
启用),该队列可以在许多处理器上提供更好的 io_service
可伸缩性。Asio 作为 Boost 的一部分首次发布。