送信受信キャッシュ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の目的は、元の記憶領域を表すキャッシュオブジェクトを作成することであり、その構成は以下のように許容される.
  • 元のメモリポインタとそのサイズ
  • PODタイプの配列(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はデータの内容を含み、メモリは自動的に
  • 増加することができる.