送信受信キャッシュasio::bufferおよびasio::streambuf
4172 ワード
asio::buffer
データの送受信は、いずれもバイトストリーム形式で処理されるため、読み取り、書き込みのためのメモリ連続の記憶領域が必要であり、その表現形式はメモリポインタとメモリサイズであり、
asio::buffer
はこの記憶領域を表すために用いられ、機能によっては可変mutable、可変constに分けられ、その定義は以下の通りである.typedef std::pair mutable_buffer;
typedef std::pair const_buffer;
個人的な理解:
asio::buffer
自体はデータの内容を持っていないので、送信/受信動作にデータ操作を行うためのアダプタと理解することができます.これは、非同期操作時にデータが常に有効であることを保証するためです.構築asio::buffer
asio::buffer
の目的は、元の記憶領域を表すキャッシュオブジェクトを作成することであり、その構成は以下のように許容される.std::array
またはstd::vector
)std::string
なお、構造が完了すると、その大きさは決定され、自動成長は行われない.
asio::bufferの操作
boost::asio::buffer_size(buffer)
boost::asio::buffer_cast(buffer)
boost::asio::buffer_copy
boost::asio::buffer(buffer+offset,size)
asio::bufferシーケンス
Boost.Asio
は、asio::buffer
の動作をサポートするためのscatter-gatter
シーケンスを提供する.asio::buffer
asio::buffer
シーケンスを使用する場合、
boost::asio::buffers_begin
およびboost::asio::buffers_end
が使用され、シーケンスの反復器タイプがboost::asio::const_buffer
またはboost::asio::mutable_buffer
であるように動作する.拡張asio::buffer
asio::buffer
自体は比較的簡単であり、それを拡張して自分のbufferをサポートするにはシーケンスのみを利用することができ、以前の理解によれば、拡張実装されたクラスはシーケンス要求の内容を含むだけでよい.例えば、const_buffer
が実現するのは以下のようなものである. typedef boost::asio::const_buffer value_type; //
typedef const boost::asio::const_buffer* const_iterator; //
const boost::asio::const_buffer* begin() const { ...; } //
const boost::asio::const_buffer* end() const { ...; } //
asio::streambufとは
asio::streambuf
は、asio_buffer
と重要な相違点であるデータ内容を含むストリームキャッシュ領域であり、asio::streambuf
は標準ライブラリのstreambuf
から継承され、すなわちasio::streambuf
は、標準ライブラリストリーム定義に適合する任意のストリームにストリームバッファとして適用することができる.asio::buffer
は、サイズが作成されると決定され、読み取り操作時には自動的に増加することはできないが、asio::streambuf
は自動成長をサポートしている.自動成長にも最大サイズ制限があり、asio::streambuf
を構築する際に最大サイズを設定することができることに注意しなければならない.いくつかの方法があります.
commit
:出力シーケンスから入力シーケンスconsume
:入力シーケンスから文字data
:入力シーケンスのキャッシュリストsize
:入力シーケンスのサイズprepare
:出力シーケンスのキャッシュリストasioの使用方法::streambuf
自身は、データ入出力として対応する送受信インタフェースに渡すことができる.
data
を用いて入力シーケンスを取得し、送信完了後に呼び出すconsume
は、送信されたコンテンツprepare
を用いて出力シーケンスを取得し、読み出しが完了するとcommit
buffers_begin
およびbuffers_end
を用いる、シーケンスを巡回してバイトストリームコンテンツasio::streambuf使用例
書き込み例:
boost::asio::streambuf b;
std::ostream os(&b);
os << "Hello, World!
";
// try sending some data in input sequence
size_t n = sock.send(b.data());
b.consume(n); // sent data is removed from input sequence
読み込み例:
boost::asio::streambuf b;// reserve 512 bytes in output sequence
boost::asio::streambuf::mutable_buffers_type bufs = b.prepare(512);
size_t n = sock.receive(bufs);
// received data is "committed" from output sequence to input sequence
b.commit(n);
std::istream is(&b);
std::string s;
is >> s;
バイトパスの例:
boost::asio::streambuf sb;
...
std::size_t n = boost::asio::read_until(sock, sb, '
');
boost::asio::streambuf::const_buffers_type bufs = sb.data();
std::string line( boost::asio::buffers_begin(bufs), boost::asio::buffers_begin(bufs) + n);
まとめ
buffer
は1つのアダプタにすぎず、元のデータソースstreambuf
はデータの内容を含み、メモリは自動的に