目录
注意:static_cast(buf.get())这部分代码将buf指针转换为void * 类型 为什么要这么做?*>
在Boost的asio里,发送数据需要用一个结构去承载,这个结构就是buffer。
关于buffer
任何网络库都有提供buffer的数据结构,所谓buffer就是接收和发送数据时缓存数据的结构。
在 Boost.Asio 中,发送和接收数据时需要使用 buffer 来承载数据。Buffer 可以被理解为用于缓存数据的结构,而在 Boost.Asio 中提供了 asio::mutable_buffer
和 asio::const_buffer
这两个结构。
asio::mutable_buffer
用于写操作,表示可以修改数据的缓冲区。asio::const_buffer
用于读操作,表示只读数据的缓冲区。
这两个结构都代表一段连续的内存空间,首字节存储了后续数据的长度。虽然这两个结构不直接用于 Asio API,但它们是构成 MutableBufferSequence
和 ConstBufferSequence
的基本单元。
MutableBufferSequence
和 ConstBufferSequence
是由多个 asio::mutable_buffer
和 asio::const_buffer
组成的结构,它们分别用于向 Asio API 提供可写入数据和只读数据的参数。可以理解为 MutableBufferSequence
的数据结构类似于 std::vector<asio::mutable_buffer>
。这样的设计可以节省空间并且更好地适应异步 I/O 操作的需求。
因此,在 Boost.Asio 中,我们可以使用 asio::mutable_buffer
和 asio::const_buffer
来创建单个的可写入或只读的缓冲区,并将它们组合成 MutableBufferSequence
和 ConstBufferSequence
以便作为参数传递给 Asio API 来进行数据的发送和接收操作。
结构如下:
Boost.Asio 提供了 buffer()
函数来简化用户对缓冲区的处理。该函数接受多种形式的字节流作为参数,并返回适配了 MutableBufferSequence
或 ConstBufferSequence
概念的对象,即 asio::mutable_buffers_1
或 asio::const_buffers_1
类型对象。
- 如果传递给
buffer()
函数的参数是只读类型,则函数返回asio::const_buffers_1
类型对象。 - 如果传递给
buffer()
函数的参数是可写类型,则返回asio::mutable_buffers_1
类型对象。
asio::const_buffers_1
和 asio::mutable_buffers_1
提供了符合 ConstBufferSequence
和 MutableBufferSequence
概念的接口,因此它们可以直接作为 Boost.Asio API 函数的参数使用。
简而言之,使用 buffer()
函数可以轻松地生成符合要求的缓冲区对象,使得用户在发送和接收数据时更加方便。
常用asio::buffer函数创建一个缓冲区
在Boost.Asio库中,asio::buffer
函数通常有两个重载版本:
-
第一个参数是指向数据的指针,第二个参数是数据的大小。这种情况下,
asio::buffer
会创建一个用于表示该数据的缓冲区对象。 -
第一个参数是数据结构或容器,第二个参数是数据的大小。这种情况下,
asio::buffer
会创建一个用于表示数据结构或容器中的数据的缓冲区对象。
Buffer的使用(比较麻烦的版本和方便的版本对比)
这个是比较麻烦的版本,还需要将原来的字符串构造成asio::const_buffer才能使用
//buffer的使用(比较麻烦的版本)
void use_const_buffer() {
std::string buf = "Hello World";
asio::const_buffer asio_buf(buf.c_str(), buf.length());
//构造出一个const_buffer
std::vector<asio::const_buffer> buffers_sequence;
buffers_sequence.push_back(asio_buf);
}
下面是比较简单的版本,可以看到与上面相对比非常的简洁
void use_buffer_str() {
asio::const_buffers_1 output_buf = asio::buffer("Hello World");
//该行是上一个函数的简化版,这个output_buf可直接作为参数传给asio的api作为数据缓存的一种结构来使用
}
创建缓冲区示例
//创建一个20字节大小的用于输入操作的缓冲区,该缓冲区包含了由buf指向的数据
void use_buffer_array() {
const size_t BUF_SIZE_BYTES = 20;
std::unique_ptr<char[]> buf(new char[BUF_SIZE_BYTES]);
//括号内为默认构造,申请一块char类型的内存地址,使其由unique_ptr类型智能指针buf接管
auto input_buf = asio::buffer(static_cast<void*>(buf.get()),BUF_SIZE_BYTES);
//这行代码是使用Boost.Asio库中的函数来创建一个用于输入操作的缓冲区。
//asio::buffer是Boost.Asio库中的一个函数,用于创建一个表示特定内存区域的缓冲区对象,以便进行异步I / O操作。
//static_cast<void*>(buf.get())这部分代码将buf指针转换为void * 类型,
//这样做是为了确保缓冲区能够被正确地传递给asio::buffer函数。这里假设buf是一个指向某种数据类型的指针。
//BUF_SIZE_BYTES是一个表示缓冲区大小的常量,它指定了要传输的数据的大小。
//综合起来,这行代码的作用是创建一个用于输入操作的缓冲区,该缓冲区包含了指向buf指针所指向的数据,
//并且数据的大小由BUF_SIZE_BYTES指定。这通常用于异步I / O操作,比如网络通信或文件读写等场景。
}
注意:static_cast<void*>(buf.get())这部分代码将buf指针转换为void * 类型 为什么要这么做?
在这里,使用 static_cast<void*>(buf.get())
将 buf
指针转换为 void*
类型的原因是为了将 buf
智能指针所管理的内存地址传递给 asio::buffer
函数。Boost.Asio库中的 asio::buffer
函数通常期望接收一个指向内存区域的 void*
类型指针以及数据的大小来创建缓冲区对象。
由于 buf
是一个 std::unique_ptr
类型的智能指针,直接将其传递给 asio::buffer
可能会导致类型不匹配的问题,因为 asio::buffer
期望的是一个 void*
类型的指针。因此,使用 static_cast<void*>(buf.get())
将 buf
指针转换为 void*
类型,以便符合函数的参数要求。
总之,这样做是为了确保能够将 buf
所管理的内存地址正确地传递给 asio::buffer
函数,并且提供符合要求的指针类型。