3 <meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
5 <link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
6 <meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
7 <link rel="home" href="../../../boost_asio.html" title="Boost.Asio">
8 <link rel="up" href="../core.html" title="Core Concepts and Functionality">
9 <link rel="prev" href="strands.html" title="Strands: Use Threads Without Explicit Locking">
10 <link rel="next" href="streams.html" title="Streams, Short Reads and Short Writes">
12 <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
13 <table cellpadding="2" width="100%"><tr>
14 <td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
15 <td align="center"><a href="../../../../../index.html">Home</a></td>
16 <td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
17 <td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
18 <td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
19 <td align="center"><a href="../../../../../more/index.htm">More</a></td>
22 <div class="spirit-nav">
23 <a accesskey="p" href="strands.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="streams.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
26 <div class="titlepage"><div><div><h4 class="title">
27 <a name="boost_asio.overview.core.buffers"></a><a class="link" href="buffers.html" title="Buffers">Buffers</a>
28 </h4></div></div></div>
30 Fundamentally, I/O involves the transfer of data to and from contiguous
31 regions of memory, called buffers. These buffers can be simply expressed
32 as a tuple consisting of a pointer and a size in bytes. However, to allow
33 the development of efficient network applications, Boost.Asio includes
34 support for scatter-gather operations. These operations involve one or
37 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
39 A scatter-read receives data into multiple buffers.
42 A gather-write transmits multiple buffers.
46 Therefore we require an abstraction to represent a collection of buffers.
47 The approach used in Boost.Asio is to define a type (actually two types)
48 to represent a single buffer. These can be stored in a container, which
49 may be passed to the scatter-gather operations.
52 In addition to specifying buffers as a pointer and size in bytes, Boost.Asio
53 makes a distinction between modifiable memory (called mutable) and non-modifiable
54 memory (where the latter is created from the storage for a const-qualified
55 variable). These two types could therefore be defined as follows:
57 <pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="keyword">void</span><span class="special">*,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">></span> <span class="identifier">mutable_buffer</span><span class="special">;</span>
58 <span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="keyword">const</span> <span class="keyword">void</span><span class="special">*,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">></span> <span class="identifier">const_buffer</span><span class="special">;</span>
61 Here, a mutable_buffer would be convertible to a const_buffer, but conversion
62 in the opposite direction is not valid.
65 However, Boost.Asio does not use the above definitions as-is, but instead
66 defines two classes: <code class="computeroutput"><span class="identifier">mutable_buffer</span></code>
67 and <code class="computeroutput"><span class="identifier">const_buffer</span></code>. The goal
68 of these is to provide an opaque representation of contiguous memory, where:
70 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
72 Types behave as std::pair would in conversions. That is, a <code class="computeroutput"><span class="identifier">mutable_buffer</span></code> is convertible to
73 a <code class="computeroutput"><span class="identifier">const_buffer</span></code>, but
74 the opposite conversion is disallowed.
77 There is protection against buffer overruns. Given a buffer instance,
78 a user can only create another buffer representing the same range of
79 memory or a sub-range of it. To provide further safety, the library
80 also includes mechanisms for automatically determining the size of
81 a buffer from an array, <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">array</span></code>
82 or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code> of POD elements, or from a
83 <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>.
86 The underlying memory is explicitly accessed using the <code class="computeroutput"><span class="identifier">data</span><span class="special">()</span></code>
87 member function. In general an application should never need to do
88 this, but it is required by the library implementation to pass the
89 raw memory to the underlying operating system functions.
93 Finally, multiple buffers can be passed to scatter-gather operations (such
94 as <a class="link" href="../../reference/read.html" title="read">read()</a> or <a class="link" href="../../reference/write.html" title="write">write()</a>)
95 by putting the buffer objects into a container. The <code class="computeroutput"><span class="identifier">MutableBufferSequence</span></code>
96 and <code class="computeroutput"><span class="identifier">ConstBufferSequence</span></code>
97 concepts have been defined so that containers such as <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span></code>,
98 <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">list</span></code>, <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span></code>
99 or <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">array</span></code> can be used.
102 <a name="boost_asio.overview.core.buffers.h0"></a>
103 <span class="phrase"><a name="boost_asio.overview.core.buffers.streambuf_for_integration_with_iostreams"></a></span><a class="link" href="buffers.html#boost_asio.overview.core.buffers.streambuf_for_integration_with_iostreams">Streambuf
104 for Integration with Iostreams</a>
107 The class <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">basic_streambuf</span></code> is derived from <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">basic_streambuf</span></code> to associate the input
108 sequence and output sequence with one or more objects of some character
109 array type, whose elements store arbitrary values. These character array
110 objects are internal to the streambuf object, but direct access to the
111 array elements is provided to permit them to be used with I/O operations,
112 such as the send or receive operations of a socket:
114 <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
115 <li class="listitem">
116 The input sequence of the streambuf is accessible via the <a class="link" href="../../reference/basic_streambuf/data.html" title="basic_streambuf::data">data()</a>
117 member function. The return type of this function meets the <code class="computeroutput"><span class="identifier">ConstBufferSequence</span></code> requirements.
119 <li class="listitem">
120 The output sequence of the streambuf is accessible via the <a class="link" href="../../reference/basic_streambuf/prepare.html" title="basic_streambuf::prepare">prepare()</a>
121 member function. The return type of this function meets the <code class="computeroutput"><span class="identifier">MutableBufferSequence</span></code> requirements.
123 <li class="listitem">
124 Data is transferred from the front of the output sequence to the back
125 of the input sequence by calling the <a class="link" href="../../reference/basic_streambuf/commit.html" title="basic_streambuf::commit">commit()</a>
128 <li class="listitem">
129 Data is removed from the front of the input sequence by calling the
130 <a class="link" href="../../reference/basic_streambuf/consume.html" title="basic_streambuf::consume">consume()</a>
135 The streambuf constructor accepts a <code class="computeroutput"><span class="identifier">size_t</span></code>
136 argument specifying the maximum of the sum of the sizes of the input sequence
137 and output sequence. Any operation that would, if successful, grow the
138 internal data beyond this limit will throw a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">length_error</span></code>
142 <a name="boost_asio.overview.core.buffers.h1"></a>
143 <span class="phrase"><a name="boost_asio.overview.core.buffers.bytewise_traversal_of_buffer_sequences"></a></span><a class="link" href="buffers.html#boost_asio.overview.core.buffers.bytewise_traversal_of_buffer_sequences">Bytewise
144 Traversal of Buffer Sequences</a>
147 The <code class="computeroutput"><span class="identifier">buffers_iterator</span><span class="special"><></span></code>
148 class template allows buffer sequences (i.e. types meeting <code class="computeroutput"><span class="identifier">MutableBufferSequence</span></code> or <code class="computeroutput"><span class="identifier">ConstBufferSequence</span></code> requirements) to
149 be traversed as though they were a contiguous sequence of bytes. Helper
150 functions called buffers_begin() and buffers_end() are also provided, where
151 the buffers_iterator<> template parameter is automatically deduced.
154 As an example, to read a single line from a socket and into a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>, you may write:
156 <pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">streambuf</span> <span class="identifier">sb</span><span class="special">;</span>
157 <span class="special">...</span>
158 <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">n</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">read_until</span><span class="special">(</span><span class="identifier">sock</span><span class="special">,</span> <span class="identifier">sb</span><span class="special">,</span> <span class="char">'\n'</span><span class="special">);</span>
159 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">streambuf</span><span class="special">::</span><span class="identifier">const_buffers_type</span> <span class="identifier">bufs</span> <span class="special">=</span> <span class="identifier">sb</span><span class="special">.</span><span class="identifier">data</span><span class="special">();</span>
160 <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">line</span><span class="special">(</span>
161 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffers_begin</span><span class="special">(</span><span class="identifier">bufs</span><span class="special">),</span>
162 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffers_begin</span><span class="special">(</span><span class="identifier">bufs</span><span class="special">)</span> <span class="special">+</span> <span class="identifier">n</span><span class="special">);</span>
165 <a name="boost_asio.overview.core.buffers.h2"></a>
166 <span class="phrase"><a name="boost_asio.overview.core.buffers.buffer_debugging"></a></span><a class="link" href="buffers.html#boost_asio.overview.core.buffers.buffer_debugging">Buffer
170 Some standard library implementations, such as the one that ships with
171 Microsoft Visual C++ 8.0 and later, provide a feature called iterator debugging.
172 What this means is that the validity of iterators is checked at runtime.
173 If a program tries to use an iterator that has been invalidated, an assertion
174 will be triggered. For example:
176 <pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">v</span><span class="special">(</span><span class="number">1</span><span class="special">)</span>
177 <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special"><</span><span class="keyword">int</span><span class="special">>::</span><span class="identifier">iterator</span> <span class="identifier">i</span> <span class="special">=</span> <span class="identifier">v</span><span class="special">.</span><span class="identifier">begin</span><span class="special">();</span>
178 <span class="identifier">v</span><span class="special">.</span><span class="identifier">clear</span><span class="special">();</span> <span class="comment">// invalidates iterators</span>
179 <span class="special">*</span><span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="comment">// assertion!</span>
182 Boost.Asio takes advantage of this feature to add buffer debugging. Consider
185 <pre class="programlisting"><span class="keyword">void</span> <span class="identifier">dont_do_this</span><span class="special">()</span>
186 <span class="special">{</span>
187 <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">msg</span> <span class="special">=</span> <span class="string">"Hello, world!"</span><span class="special">;</span>
188 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">async_write</span><span class="special">(</span><span class="identifier">sock</span><span class="special">,</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(</span><span class="identifier">msg</span><span class="special">),</span> <span class="identifier">my_handler</span><span class="special">);</span>
189 <span class="special">}</span>
192 When you call an asynchronous read or write you need to ensure that the
193 buffers for the operation are valid until the completion handler is called.
194 In the above example, the buffer is the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
195 variable <code class="computeroutput"><span class="identifier">msg</span></code>. This variable
196 is on the stack, and so it goes out of scope before the asynchronous operation
197 completes. If you're lucky then the application will crash, but random
198 failures are more likely.
201 When buffer debugging is enabled, Boost.Asio stores an iterator into the
202 string until the asynchronous operation completes, and then dereferences
203 it to check its validity. In the above example you would observe an assertion
204 failure just before Boost.Asio tries to call the completion handler.
207 This feature is automatically made available for Microsoft Visual Studio
208 8.0 or later and for GCC when <code class="computeroutput"><span class="identifier">_GLIBCXX_DEBUG</span></code>
209 is defined. There is a performance cost to this checking, so buffer debugging
210 is only enabled in debug builds. For other compilers it may be enabled
211 by defining <code class="computeroutput"><span class="identifier">BOOST_ASIO_ENABLE_BUFFER_DEBUGGING</span></code>.
212 It can also be explicitly disabled by defining <code class="computeroutput"><span class="identifier">BOOST_ASIO_DISABLE_BUFFER_DEBUGGING</span></code>.
215 <a name="boost_asio.overview.core.buffers.h3"></a>
216 <span class="phrase"><a name="boost_asio.overview.core.buffers.see_also"></a></span><a class="link" href="buffers.html#boost_asio.overview.core.buffers.see_also">See
220 <a class="link" href="../../reference/buffer.html" title="buffer">buffer</a>, <a class="link" href="../../reference/buffers_begin.html" title="buffers_begin">buffers_begin</a>,
221 <a class="link" href="../../reference/buffers_end.html" title="buffers_end">buffers_end</a>, <a class="link" href="../../reference/buffers_iterator.html" title="buffers_iterator">buffers_iterator</a>,
222 <a class="link" href="../../reference/const_buffer.html" title="const_buffer">const_buffer</a>,
223 <a class="link" href="../../reference/const_buffers_1.html" title="const_buffers_1">const_buffers_1</a>,
224 <a class="link" href="../../reference/mutable_buffer.html" title="mutable_buffer">mutable_buffer</a>,
225 <a class="link" href="../../reference/mutable_buffers_1.html" title="mutable_buffers_1">mutable_buffers_1</a>,
226 <a class="link" href="../../reference/streambuf.html" title="streambuf">streambuf</a>, <a class="link" href="../../reference/ConstBufferSequence.html" title="Constant buffer sequence requirements">ConstBufferSequence</a>,
227 <a class="link" href="../../reference/MutableBufferSequence.html" title="Mutable buffer sequence requirements">MutableBufferSequence</a>,
228 <a class="link" href="../../examples/cpp03_examples.html#boost_asio.examples.cpp03_examples.buffers">buffers example
229 (C++03)</a>, <a class="link" href="../../examples/cpp11_examples.html#boost_asio.examples.cpp11_examples.buffers">buffers
233 <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
234 <td align="left"></td>
235 <td align="right"><div class="copyright-footer">Copyright © 2003-2019 Christopher M. Kohlhoff<p>
236 Distributed under the Boost Software License, Version 1.0. (See accompanying
237 file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
242 <div class="spirit-nav">
243 <a accesskey="p" href="strands.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../core.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../boost_asio.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="streams.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>