buffer
函数用于创建一个缓冲区对象,以表示原始内存、POD 元素数组、POD 元素向量或 std::string。
从现有缓冲区创建一个新的可修改缓冲区。
mutable_buffer buffer( const mutable_buffer & b); » more... mutable_buffer buffer( const mutable_buffer & b, std::size_t max_size_in_bytes); » more...
从现有缓冲区创建一个新的不可修改缓冲区。
const_buffer buffer( const const_buffer & b); » more... const_buffer buffer( const const_buffer & b, std::size_t max_size_in_bytes); » more...
创建一个新的可修改缓冲区,表示给定的内存范围。
mutable_buffer buffer( void * data, std::size_t size_in_bytes); » more...
创建一个新的不可修改缓冲区,表示给定的内存范围。
const_buffer buffer( const void * data, std::size_t size_in_bytes); » more...
创建一个新的可修改缓冲区,表示给定的 POD 数组。
template< typename PodType, std::size_t N> mutable_buffer buffer( PodType((&data)[N]); » more... template< typename PodType, std::size_t N> mutable_buffer buffer( PodType((&data)[N], std::size_t max_size_in_bytes); » more...
创建一个新的不可修改缓冲区,表示给定的 POD 数组。
template< typename PodType, std::size_t N> const_buffer buffer( const PodType((&data)[N]); » more... template< typename PodType, std::size_t N> const_buffer buffer( const PodType((&data)[N], std::size_t max_size_in_bytes); » more...
创建一个新的可修改缓冲区,表示给定的 POD 数组。
template< typename PodType, std::size_t N> mutable_buffer buffer( boost::array< PodType, N > & data); » more... template< typename PodType, std::size_t N> mutable_buffer buffer( boost::array< PodType, N > & data, std::size_t max_size_in_bytes); » more...
创建一个新的不可修改缓冲区,表示给定的 POD 数组。
template< typename PodType, std::size_t N> const_buffer buffer( boost::array< const PodType, N > & data); » more... template< typename PodType, std::size_t N> const_buffer buffer( boost::array< const PodType, N > & data, std::size_t max_size_in_bytes); » more...
创建一个新的可修改缓冲区,表示给定的 POD 数组。
template< typename PodType, std::size_t N> mutable_buffer buffer( std::array< PodType, N > & data); » more... template< typename PodType, std::size_t N> mutable_buffer buffer( std::array< PodType, N > & data, std::size_t max_size_in_bytes); » more...
创建一个新的不可修改缓冲区,表示给定的 POD 数组。
template< typename PodType, std::size_t N> const_buffer buffer( std::array< const PodType, N > & data); » more... template< typename PodType, std::size_t N> const_buffer buffer( std::array< const PodType, N > & data, std::size_t max_size_in_bytes); » more...
创建一个新的可修改缓冲区,表示给定的 POD 向量。
template< typename PodType, typename Allocator> mutable_buffer buffer( std::vector< PodType, Allocator > & data); » more... template< typename PodType, typename Allocator> mutable_buffer buffer( std::vector< PodType, Allocator > & data, std::size_t max_size_in_bytes); » more...
创建一个新的不可修改缓冲区,表示给定的 POD 向量。
template< typename PodType, typename Allocator> const_buffer buffer( const std::vector< PodType, Allocator > & data); » more... template< typename PodType, typename Allocator> const_buffer buffer( const std::vector< PodType, Allocator > & data, std::size_t max_size_in_bytes); » more...
创建一个新的可修改缓冲区,表示给定的字符串。
template< typename Elem, typename Traits, typename Allocator> mutable_buffer buffer( std::basic_string< Elem, Traits, Allocator > & data); » more... template< typename Elem, typename Traits, typename Allocator> mutable_buffer buffer( std::basic_string< Elem, Traits, Allocator > & data, std::size_t max_size_in_bytes); » more...
创建一个新的不可修改缓冲区,表示给定的字符串。
template< typename Elem, typename Traits, typename Allocator> const_buffer buffer( const std::basic_string< Elem, Traits, Allocator > & data); » more... template< typename Elem, typename Traits, typename Allocator> const_buffer buffer( const std::basic_string< Elem, Traits, Allocator > & data, std::size_t max_size_in_bytes); » more...
创建一个新的不可修改缓冲区,表示给定的 string_view。
template< typename Elem, typename Traits> const_buffer buffer( basic_string_view< Elem, Traits > data); » more...
创建一个新的不可修改缓冲区,表示给定的字符串。
template< typename Elem, typename Traits> const_buffer buffer( basic_string_view< Elem, Traits > data, std::size_t max_size_in_bytes); » more...
从连续容器创建一个新的可修改缓冲区。
template< typename T> mutable_buffer buffer( T & data, constraint_t< is_contiguous_iterator< typename T::iterator >::value, defaulted_constraint > = defaulted_constraint(), constraint_t< !is_convertible< T, const_buffer >::value, defaulted_constraint > = defaulted_constraint(), constraint_t< !is_convertible< T, mutable_buffer >::value, defaulted_constraint > = defaulted_constraint(), constraint_t< !is_const< remove_reference_t< typename std::iterator_traits< typename T::iterator >::reference > >::value, defaulted_constraint > = defaulted_constraint()); » more... template< typename T> mutable_buffer buffer( T & data, std::size_t max_size_in_bytes, constraint_t< is_contiguous_iterator< typename T::iterator >::value, defaulted_constraint > = defaulted_constraint(), constraint_t< !is_convertible< T, const_buffer >::value, defaulted_constraint > = defaulted_constraint(), constraint_t< !is_convertible< T, mutable_buffer >::value, defaulted_constraint > = defaulted_constraint(), constraint_t< !is_const< remove_reference_t< typename std::iterator_traits< typename T::iterator >::reference > >::value, defaulted_constraint > = defaulted_constraint()); » more...
从连续容器创建一个新的不可修改缓冲区。
template< typename T> const_buffer buffer( T & data, constraint_t< is_contiguous_iterator< typename T::iterator >::value, defaulted_constraint > = defaulted_constraint(), constraint_t< !is_convertible< T, const_buffer >::value, defaulted_constraint > = defaulted_constraint(), constraint_t< !is_convertible< T, mutable_buffer >::value, defaulted_constraint > = defaulted_constraint(), constraint_t< is_const< remove_reference_t< typename std::iterator_traits< typename T::iterator >::reference > >::value, defaulted_constraint > = defaulted_constraint()); » more... template< typename T> const_buffer buffer( T & data, std::size_t max_size_in_bytes, constraint_t< is_contiguous_iterator< typename T::iterator >::value, defaulted_constraint > = defaulted_constraint(), constraint_t< !is_convertible< T, const_buffer >::value, defaulted_constraint > = defaulted_constraint(), constraint_t< !is_convertible< T, mutable_buffer >::value, defaulted_constraint > = defaulted_constraint(), constraint_t< is_const< remove_reference_t< typename std::iterator_traits< typename T::iterator >::reference > >::value, defaulted_constraint > = defaulted_constraint()); » more... template< typename T> const_buffer buffer( const T & data, constraint_t< is_contiguous_iterator< typename T::const_iterator >::value, defaulted_constraint > = defaulted_constraint(), constraint_t< !is_convertible< T, const_buffer >::value, defaulted_constraint > = defaulted_constraint(), constraint_t< !is_convertible< T, mutable_buffer >::value, defaulted_constraint > = defaulted_constraint()); » more... template< typename T> const_buffer buffer( const T & data, std::size_t max_size_in_bytes, constraint_t< is_contiguous_iterator< typename T::const_iterator >::value, defaulted_constraint > = defaulted_constraint(), constraint_t< !is_convertible< T, const_buffer >::value, defaulted_constraint > = defaulted_constraint(), constraint_t< !is_convertible< T, mutable_buffer >::value, defaulted_constraint > = defaulted_constraint()); » more...
获取表示整个已注册缓冲区的缓冲区。
mutable_registered_buffer buffer( const mutable_registered_buffer & b); » more... const_registered_buffer buffer( const const_registered_buffer & b); » more...
获取表示已注册缓冲区一部分的缓冲区。
mutable_registered_buffer buffer( const mutable_registered_buffer & b, std::size_t n); » more... const_registered_buffer buffer( const const_registered_buffer & b, std::size_t n); » more...
缓冲区对象将连续内存区域表示为一个 2 元组,包含一个指针和以字节为单位的大小。形式为 {void*, size_t}
的元组指定一个可变(可修改)的内存区域。类似地,形式为 {const void*, size_t}
的元组指定一个常量(不可修改)的内存区域。这两种形式分别对应于 mutable_buffer
和 const_buffer
类。为了反映 C++ 的转换规则,mutable_buffer
可以隐式转换为 const_buffer
,反之则不允许。
最简单的用例涉及读取或写入指定大小的单个缓冲区
sock.send(boost::asio::buffer(data, size));
在上面的示例中,buffer
的返回值满足 ConstBufferSequence 概念的要求,因此可以直接传递给套接字的写入函数。为可修改内存创建的缓冲区也满足 MutableBufferSequence 概念的要求。
可以从内置数组、std::vector、std::array 或 boost::array 的 POD 元素创建单个缓冲区。这有助于通过自动确定缓冲区的大小来防止缓冲区溢出
char d1[128]; size_t bytes_transferred = sock.receive(boost::asio::buffer(d1)); std::vector<char> d2(128); bytes_transferred = sock.receive(boost::asio::buffer(d2)); std::array<char, 128> d3; bytes_transferred = sock.receive(boost::asio::buffer(d3)); boost::array<char, 128> d4; bytes_transferred = sock.receive(boost::asio::buffer(d4));
在以上所有三种情况下,创建的缓冲区均为 128 字节长。请注意,在创建或使用缓冲区时,向量 永远不会 自动调整大小。缓冲区大小是使用向量的 size()
成员函数确定的,而不是它的容量。
可以使用 data()
和 size()
成员函数访问缓冲区的内容
boost::asio::mutable_buffer b1 = ...; std::size_t s1 = b1.size(); unsigned char* p1 = static_cast<unsigned char*>(b1.data()); boost::asio::const_buffer b2 = ...; std::size_t s2 = b2.size(); const void* p2 = b2.data();
data()
成员函数允许违反类型安全,因此在应用程序代码中应仔细考虑其使用。
为了方便起见,提供了一个 buffer_size
函数,该函数可与缓冲区和缓冲区序列(即满足 ConstBufferSequence 或 MutableBufferSequence 类型要求的类型)一起使用。在这种情况下,该函数返回序列中所有缓冲区的总大小。
buffer_copy
函数可用于在单个缓冲区和缓冲区序列之间复制原始字节。
特别是,当与 buffer_size
函数一起使用时,buffer_copy
函数可用于线性化缓冲区序列。例如
vector<const_buffer> buffers = ...; vector<unsigned char> data(boost::asio::buffer_size(buffers)); boost::asio::buffer_copy(boost::asio::buffer(data), buffers);
请注意,buffer_copy
是用 memcpy
实现的,因此它不能用于在重叠的内存区域之间进行复制。
缓冲区对象不拥有其引用的内存的所有权。应用程序有责任确保内存区域在不再需要用于 I/O 操作之前保持有效。当内存不再可用时,该缓冲区被认为已失效。
对于接受 std::vector 类型参数的 buffer
重载,返回的缓冲区对象会被任何也会使引用、指针和迭代器无效的向量操作失效,这些引用、指针和迭代器指向序列中的元素 (C++ Std, 23.2.4)
对于接受 std::basic_string 类型参数的 buffer
重载,返回的缓冲区对象会根据为引用、指针和迭代器定义的失效规则失效,这些引用、指针和迭代器指向序列中的元素 (C++ Std, 21.3)。
可以使用简单的算术以安全的方式来操作缓冲区对象,这有助于防止缓冲区溢出。考虑按如下方式初始化的数组
boost::array<char, 6> a = { 'a', 'b', 'c', 'd', 'e' };
使用以下代码创建的缓冲区对象 b1
b1 = boost::asio::buffer(a);
表示整个数组,{ 'a', 'b', 'c', 'd', 'e' }
。可以使用 buffer
函数的可选第二个参数来限制缓冲区的大小(以字节为单位)
b2 = boost::asio::buffer(a, 3);
使得 b2
表示数据 { 'a', 'b', 'c' }
。即使大小参数超过数组的实际大小,创建的缓冲区对象的大小也将被限制为数组的大小。
可以将偏移量应用于现有缓冲区以创建一个新的缓冲区
b3 = b1 + 2;
其中 b3
将设置为表示 { 'c', 'd', 'e' }
。如果偏移量超过现有缓冲区的大小,则新创建的缓冲区将为空。
可以指定偏移量和大小来创建一个与现有缓冲区中特定字节范围对应的缓冲区
b4 = boost::asio::buffer(b1 + 1, 3);
因此 b4
将引用字节 { 'b', 'c', 'd' }
。
要使用多个缓冲区(即分散/聚集 I/O)进行读取或写入,可以将多个缓冲区对象分配到支持 MutableBufferSequence(用于读取)或 ConstBufferSequence(用于写入)概念的容器中
char d1[128]; std::vector<char> d2(128); boost::array<char, 128> d3; boost::array<mutable_buffer, 3> bufs1 = { boost::asio::buffer(d1), boost::asio::buffer(d2), boost::asio::buffer(d3) }; bytes_transferred = sock.receive(bufs1); std::vector<const_buffer> bufs2; bufs2.push_back(boost::asio::buffer(d1)); bufs2.push_back(boost::asio::buffer(d2)); bufs2.push_back(boost::asio::buffer(d3)); bytes_transferred = sock.send(bufs2);
在命名空间 boost::asio::buffer_literals
中定义的 _buf
字面量后缀可用于从字符串、二进制整数和十六进制整数字面量创建 const_buffer
对象。例如
using namespace boost::asio::buffer_literals; boost::asio::const_buffer b1 = "hello"_buf; boost::asio::const_buffer b2 = 0xdeadbeef_buf; boost::asio::const_buffer b3 = 0x0123456789abcdef0123456789abcdef_buf; boost::asio::const_buffer b4 = 0b1010101011001100_buf;
请注意,与缓冲区字面量关联的内存在该程序的生命周期内有效。这意味着该缓冲区可以安全地用于异步操作。
头文件:boost/asio/buffer.hpp
便捷头文件:boost/asio.hpp