1<html> 2<head> 3<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 4<title>Refresher</title> 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="../../index.html" title="Chapter 1. Boost.Beast"> 8<link rel="up" href="../using_io.html" title="Networking"> 9<link rel="prev" href="../using_io.html" title="Networking"> 10<link rel="next" href="stream_types.html" title="Streams"> 11</head> 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> 20</tr></table> 21<hr> 22<div class="spirit-nav"> 23<a accesskey="p" href="../using_io.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../using_io.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="stream_types.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> 24</div> 25<div class="section"> 26<div class="titlepage"><div><div><h3 class="title"> 27<a name="beast.using_io.asio_refresher"></a><a class="link" href="asio_refresher.html" title="Refresher">Refresher</a> 28</h3></div></div></div> 29<p> 30 To use Beast effectively, a prior understanding of Networking is required. 31 This section reviews these concepts as a reminder and guide for further learning. 32 </p> 33<p> 34 A <a href="https://en.wikipedia.org/wiki/Computer_network" target="_top"><span class="emphasis"><em>network</em></span></a> 35 allows programs located anywhere to exchange information after opting-in 36 to communications by establishing a <a href="https://en.wikipedia.org/wiki/Data_link" target="_top"><span class="emphasis"><em>connection</em></span></a>. 37 Data may be reliably transferred across a connection in both directions (<a href="https://en.wikipedia.org/wiki/Duplex_(telecommunications)" target="_top"><span class="emphasis"><em>full-duplex</em></span></a>) 38 with bytes arriving in the same order they were sent. These connections, 39 along with the objects and types used to represent them, are collectively 40 termed <a class="link" href="../concepts/streams.html" title="Streams"><span class="emphasis"><em>streams</em></span></a>. 41 The computer or device attached to the network is called a <a href="https://en.wikipedia.org/wiki/Host_(network)" target="_top"><span class="emphasis"><em>host</em></span></a>, 42 and the program on the other end of an established connection is called a 43 <a href="https://en.wikipedia.org/wiki/Peer-to-peer" target="_top"><span class="emphasis"><em>peer</em></span></a>. 44 </p> 45<p> 46 The <a href="https://en.wikipedia.org/wiki/Internet" target="_top"><span class="emphasis"><em>internet</em></span></a> 47 is a global network of interconnected computers that use a variety of standardized 48 communication protocols to exchange information. The most popular protocol 49 is <a href="https://en.wikipedia.org/wiki/Transmission_Control_Protocol" target="_top"><span class="emphasis"><em>TCP/IP</em></span></a>, 50 which this library relies on exclusively. The protocol takes care of the 51 low level details so that applications see a <span class="emphasis"><em>stream</em></span>, 52 which is the reliable, full-duplex connection carrying the ordered set of 53 bytes described above. A <a href="https://en.wikipedia.org/wiki/Server_(computing)" target="_top"><span class="emphasis"><em>server</em></span></a> 54 is a powerful, always-on host at a well-known network name or network address 55 which provides data services. A <a href="https://en.wikipedia.org/wiki/Client_(computing)" target="_top"><span class="emphasis"><em>client</em></span></a> 56 is a transient peer which connects to a server to exchange data, and goes 57 offline. 58 </p> 59<p> 60 A vendor supplies a program called a <a href="https://en.wikipedia.org/wiki/Device_driver" target="_top"><span class="emphasis"><em>device 61 driver</em></span></a>, enabling networking hardware such as an <a href="https://en.wikipedia.org/wiki/Network_interface_controller" target="_top"><span class="emphasis"><em>ethernet 62 adaptor</em></span></a> to talk to the operating system. This in turn 63 permits running programs to interact with networking using various flavors 64 of interfaces such as <a href="https://en.wikipedia.org/wiki/Berkeley_sockets" target="_top"><span class="emphasis"><em>Berkeley 65 sockets</em></span></a> or <a href="https://en.wikipedia.org/wiki/Winsock" target="_top"><span class="emphasis"><em>Windows 66 Sockets 2</em></span></a> ("Winsock"). 67 </p> 68<p> 69 Networking in C++, represented by <a href="../../../../../../libs/asio/index.html" target="_top">Boost.Asio</a>, 70 <a href="https://think-async.com/Asio/" target="_top">Asio</a>, and <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/n4771.pdf" target="_top">Networking 71 TS</a>, provides a layer of abstraction to interact portably with the 72 operating system facilities for not just networking but general <a href="https://en.wikipedia.org/wiki/Input/output" target="_top"><span class="emphasis"><em>input/output</em></span></a> 73 ("I/O"). 74 </p> 75<h5> 76<a name="beast.using_io.asio_refresher.h0"></a> 77 <span class="phrase"><a name="beast.using_io.asio_refresher.buffers"></a></span><a class="link" href="asio_refresher.html#beast.using_io.asio_refresher.buffers">Buffers</a> 78 </h5> 79<p> 80 A <a href="https://en.wikipedia.org/wiki/Data_buffer" target="_top"><span class="emphasis"><em>buffer</em></span></a> 81 holds a contiguous sequence of bytes used when performing I/O. The types 82 <a href="../../../../../../doc/html/boost_asio/reference/const_buffer.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">const_buffer</span></code></a> 83 and <a href="../../../../../../doc/html/boost_asio/reference/mutable_buffer.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">mutable_buffer</span></code></a> 84 represent these memory regions as type-safe pointer/size pairs: 85 </p> 86<pre class="programlisting"><span class="identifier">net</span><span class="special">::</span><span class="identifier">const_buffer</span> <span class="identifier">cb</span><span class="special">(</span><span class="string">"Hello, world!"</span><span class="special">,</span> <span class="number">13</span><span class="special">);</span> 87<span class="identifier">assert</span><span class="special">(</span><span class="identifier">string_view</span><span class="special">(</span><span class="keyword">reinterpret_cast</span><span class="special"><</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*>(</span> 88 <span class="identifier">cb</span><span class="special">.</span><span class="identifier">data</span><span class="special">()),</span> <span class="identifier">cb</span><span class="special">.</span><span class="identifier">size</span><span class="special">())</span> <span class="special">==</span> <span class="string">"Hello, world!"</span><span class="special">);</span> 89 90<span class="keyword">char</span> <span class="identifier">storage</span><span class="special">[</span><span class="number">13</span><span class="special">];</span> 91<span class="identifier">net</span><span class="special">::</span><span class="identifier">mutable_buffer</span> <span class="identifier">mb</span><span class="special">(</span><span class="identifier">storage</span><span class="special">,</span> <span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">storage</span><span class="special">));</span> 92<span class="identifier">std</span><span class="special">::</span><span class="identifier">memcpy</span><span class="special">(</span><span class="identifier">mb</span><span class="special">.</span><span class="identifier">data</span><span class="special">(),</span> <span class="identifier">cb</span><span class="special">.</span><span class="identifier">data</span><span class="special">(),</span> <span class="identifier">mb</span><span class="special">.</span><span class="identifier">size</span><span class="special">());</span> 93<span class="identifier">assert</span><span class="special">(</span><span class="identifier">string_view</span><span class="special">(</span><span class="keyword">reinterpret_cast</span><span class="special"><</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*>(</span> 94 <span class="identifier">mb</span><span class="special">.</span><span class="identifier">data</span><span class="special">()),</span> <span class="identifier">mb</span><span class="special">.</span><span class="identifier">size</span><span class="special">())</span> <span class="special">==</span> <span class="string">"Hello, world!"</span><span class="special">);</span> 95</pre> 96<div class="tip"><table border="0" summary="Tip"> 97<tr> 98<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../doc/src/images/tip.png"></td> 99<th align="left">Tip</th> 100</tr> 101<tr><td align="left" valign="top"><p> 102 <code class="computeroutput"><span class="identifier">const_buffer</span></code> and <code class="computeroutput"><span class="identifier">mutable_buffer</span></code> are preferred over <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">span</span><span class="special"><</span><span class="identifier">byte</span><span class="special">></span></code> 103 and <code class="computeroutput"><span class="identifier">span</span><span class="special"><</span><span class="identifier">byte</span> <span class="keyword">const</span><span class="special">></span></code> because <a href="https://en.cppreference.com/w/cpp/container/span" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">span</span></code></a> does too much. It not only 104 type-erases the original pointer but also recasts it to a pointer-to-byte. 105 The operating system doesn't care about this, but if a user wants to send 106 and receive an array of some other type, presenting it as an array of bytes 107 which supports bitwise operations is unnecessary. Custom buffer types also 108 enable implementations to provide targeted features such as <a href="../../../../../../doc/html/boost_asio/overview/core/buffers.html#boost_asio.overview.core.buffers.buffer_debugging" target="_top"><span class="emphasis"><em>buffer 109 debugging</em></span></a> without changing the more general vocabulary 110 types. 111 </p></td></tr> 112</table></div> 113<p> 114 The concepts <a href="../../../../../../doc/html/boost_asio/reference/ConstBufferSequence.html" target="_top"><span class="emphasis"><em>ConstBufferSequence</em></span></a> 115 and <a href="../../../../../../doc/html/boost_asio/reference/MutableBufferSequence.html" target="_top"><span class="emphasis"><em>MutableBufferSequence</em></span></a> 116 describe bidirectional ranges whose value type is convertible to <code class="computeroutput"><span class="identifier">const_buffer</span></code> and <code class="computeroutput"><span class="identifier">mutable_buffer</span></code> 117 respectively. These sequences allow transacting with multiple buffers in 118 a single function call, a technique called <a href="https://en.wikipedia.org/wiki/Vectored_I/O" target="_top"><span class="emphasis"><em>scatter/gather 119 I/O</em></span></a>. Buffers and buffer sequences are non-owning; copies 120 produce shallow references and not duplicates of the underlying memory. Each 121 of these statements declares a buffer sequence: 122 </p> 123<pre class="programlisting"><span class="identifier">net</span><span class="special">::</span><span class="identifier">const_buffer</span> <span class="identifier">b1</span><span class="special">;</span> <span class="comment">// a ConstBufferSequence by definition</span> 124<span class="identifier">net</span><span class="special">::</span><span class="identifier">mutable_buffer</span> <span class="identifier">b2</span><span class="special">;</span> <span class="comment">// a MutableBufferSequence by definition</span> 125<span class="identifier">std</span><span class="special">::</span><span class="identifier">array</span><span class="special"><</span><span class="identifier">net</span><span class="special">::</span><span class="identifier">const_buffer</span><span class="special">,</span> <span class="number">3</span><span class="special">></span> <span class="identifier">b3</span><span class="special">;</span> <span class="comment">// A ConstBufferSequence by named requirements</span> 126</pre> 127<p> 128 The functions <a href="../../../../../../doc/html/boost_asio/reference/buffer_size.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">buffer_size</span></code></a> 129 and <a href="../../../../../../doc/html/boost_asio/reference/buffer_copy.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">buffer_copy</span></code></a> 130 determine the total number of bytes in a buffer sequence, and transfer some 131 or all of bytes from one buffer sequence to another respectively. The function 132 <code class="computeroutput"><span class="identifier">buffer_size</span></code> is a customization 133 point: user defined overloads in foreign namespaces are possible, and callers 134 should invoke <code class="computeroutput"><span class="identifier">buffer_size</span></code> 135 without namespace qualification. The functions <a href="../../../../../../doc/html/boost_asio/reference/buffer_sequence_begin.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">buffer_sequence_begin</span></code></a> 136 and <a href="../../../../../../doc/html/boost_asio/reference/buffer_sequence_end.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">buffer_sequence_end</span></code></a> 137 are used to obtain a pair of iterators for traversing the sequence. Beast 138 provides a set of buffer sequence types and algorithms such as <a class="link" href="../ref/boost__beast__buffers_cat.html" title="buffers_cat"><code class="computeroutput"><span class="identifier">buffers_cat</span></code></a>, <a class="link" href="../ref/boost__beast__buffers_front.html" title="buffers_front"><code class="computeroutput"><span class="identifier">buffers_front</span></code></a>, <a class="link" href="../ref/boost__beast__buffers_prefix.html" title="buffers_prefix"><code class="computeroutput"><span class="identifier">buffers_prefix</span></code></a>, <a class="link" href="../ref/boost__beast__buffers_range.html" title="buffers_range"><code class="computeroutput"><span class="identifier">buffers_range</span></code></a>, and <a class="link" href="../ref/boost__beast__buffers_suffix.html" title="buffers_suffix"><code class="computeroutput"><span class="identifier">buffers_suffix</span></code></a>. This example returns 139 the bytes in a buffer sequence as a string: 140 </p> 141<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">ConstBufferSequence</span><span class="special">></span> 142<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">string_from_buffers</span> <span class="special">(</span><span class="identifier">ConstBufferSequence</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">buffers</span><span class="special">)</span> 143<span class="special">{</span> 144 <span class="comment">// check that the type meets the requirements using the provided type traits</span> 145 <span class="keyword">static_assert</span><span class="special">(</span> 146 <span class="identifier">net</span><span class="special">::</span><span class="identifier">is_const_buffer_sequence</span><span class="special"><</span><span class="identifier">ConstBufferSequence</span><span class="special">>::</span><span class="identifier">value</span><span class="special">,</span> 147 <span class="string">"ConstBufferSequence type requirements not met"</span><span class="special">);</span> 148 149 <span class="comment">// optimization: reserve all the space for the string first</span> 150 <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">result</span><span class="special">;</span> 151 <span class="identifier">result</span><span class="special">.</span><span class="identifier">reserve</span><span class="special">(</span><span class="identifier">beast</span><span class="special">::</span><span class="identifier">buffer_bytes</span><span class="special">(</span><span class="identifier">buffers</span><span class="special">));</span> <span class="comment">// beast version of net::buffer_size</span> 152 153 <span class="comment">// iterate over each buffer in the sequence and append it to the string</span> 154 <span class="keyword">for</span><span class="special">(</span><span class="keyword">auto</span> <span class="identifier">it</span> <span class="special">=</span> <span class="identifier">net</span><span class="special">::</span><span class="identifier">buffer_sequence_begin</span><span class="special">(</span><span class="identifier">buffers</span><span class="special">);</span> <span class="comment">// returns an iterator to beginning of the sequence</span> 155 <span class="identifier">it</span> <span class="special">!=</span> <span class="identifier">net</span><span class="special">::</span><span class="identifier">buffer_sequence_end</span><span class="special">(</span><span class="identifier">buffers</span><span class="special">);)</span> <span class="comment">// returns a past-the-end iterator to the sequence</span> 156 <span class="special">{</span> 157 <span class="comment">// A buffer sequence iterator's value_type is always convertible to net::const_buffer</span> 158 <span class="identifier">net</span><span class="special">::</span><span class="identifier">const_buffer</span> <span class="identifier">buffer</span> <span class="special">=</span> <span class="special">*</span><span class="identifier">it</span><span class="special">++;</span> 159 160 <span class="comment">// A cast is always required to out-out of type-safety</span> 161 <span class="identifier">result</span><span class="special">.</span><span class="identifier">append</span><span class="special">(</span><span class="keyword">static_cast</span><span class="special"><</span><span class="keyword">char</span> <span class="keyword">const</span><span class="special">*>(</span><span class="identifier">buffer</span><span class="special">.</span><span class="identifier">data</span><span class="special">()),</span> <span class="identifier">buffer</span><span class="special">.</span><span class="identifier">size</span><span class="special">());</span> 162 <span class="special">}</span> 163 <span class="keyword">return</span> <span class="identifier">result</span><span class="special">;</span> 164<span class="special">}</span> 165</pre> 166<p> 167 The <a class="link" href="../concepts/DynamicBuffer.html" title="DynamicBuffer"><span class="emphasis"><em>DynamicBuffer</em></span></a> 168 concept defines a resizable buffer sequence interface. Algorithms may be 169 expressed in terms of dynamic buffers when the memory requirements are not 170 known ahead of time, for example when reading an HTTP message from a stream. 171 Beast provides a well-rounded collection of dynamic buffer types such as 172 <a class="link" href="../ref/boost__beast__buffers_adaptor.html" title="buffers_adaptor"><code class="computeroutput"><span class="identifier">buffers_adaptor</span></code></a>, 173 <a class="link" href="../ref/boost__beast__flat_buffer.html" title="flat_buffer"><code class="computeroutput"><span class="identifier">flat_buffer</span></code></a>, 174 <a class="link" href="../ref/boost__beast__multi_buffer.html" title="multi_buffer"><code class="computeroutput"><span class="identifier">multi_buffer</span></code></a>, 175 and <a class="link" href="../ref/boost__beast__static_buffer.html" title="static_buffer"><code class="computeroutput"><span class="identifier">static_buffer</span></code></a>. 176 The following function reads data from a <a class="link" href="../ref/boost__beast__tcp_stream.html" title="tcp_stream"><code class="computeroutput"><span class="identifier">tcp_stream</span></code></a> into a dynamic buffer 177 until it encountering a newline character, using <a href="../../../../../../doc/html/boost_asio/reference/buffers_iterator.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">buffers_iterator</span></code></a> 178 to treat the contents of the buffer as a range of characters: 179 </p> 180<pre class="programlisting"><span class="comment">// Read a line ending in '\n' from a socket, returning</span> 181<span class="comment">// the number of characters up to but not including the newline</span> 182<span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">DynamicBuffer</span><span class="special">></span> 183<span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">read_line</span><span class="special">(</span><span class="identifier">net</span><span class="special">::</span><span class="identifier">ip</span><span class="special">::</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">&</span> <span class="identifier">sock</span><span class="special">,</span> <span class="identifier">DynamicBuffer</span><span class="special">&</span> <span class="identifier">buffer</span><span class="special">)</span> 184<span class="special">{</span> 185 <span class="comment">// this alias keeps things readable</span> 186 <span class="keyword">using</span> <span class="identifier">range</span> <span class="special">=</span> <span class="identifier">net</span><span class="special">::</span><span class="identifier">buffers_iterator</span><span class="special"><</span> 187 <span class="keyword">typename</span> <span class="identifier">DynamicBuffer</span><span class="special">::</span><span class="identifier">const_buffers_type</span><span class="special">>;</span> 188 189 <span class="keyword">for</span><span class="special">(;;)</span> 190 <span class="special">{</span> 191 <span class="comment">// get iterators representing the range of characters in the buffer</span> 192 <span class="keyword">auto</span> <span class="identifier">begin</span> <span class="special">=</span> <span class="identifier">range</span><span class="special">::</span><span class="identifier">begin</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">.</span><span class="identifier">data</span><span class="special">());</span> 193 <span class="keyword">auto</span> <span class="identifier">end</span> <span class="special">=</span> <span class="identifier">range</span><span class="special">::</span><span class="identifier">end</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">.</span><span class="identifier">data</span><span class="special">());</span> 194 195 <span class="comment">// search for "\n" and return if found</span> 196 <span class="keyword">auto</span> <span class="identifier">pos</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">find</span><span class="special">(</span><span class="identifier">begin</span><span class="special">,</span> <span class="identifier">end</span><span class="special">,</span> <span class="char">'\n'</span><span class="special">);</span> 197 <span class="keyword">if</span><span class="special">(</span><span class="identifier">pos</span> <span class="special">!=</span> <span class="identifier">range</span><span class="special">::</span><span class="identifier">end</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">.</span><span class="identifier">data</span><span class="special">()))</span> 198 <span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">distance</span><span class="special">(</span><span class="identifier">begin</span><span class="special">,</span> <span class="identifier">end</span><span class="special">);</span> 199 200 <span class="comment">// Determine the number of bytes to read,</span> 201 <span class="comment">// using available capacity in the buffer first.</span> 202 <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">bytes_to_read</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">min</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">>(</span> 203 <span class="identifier">std</span><span class="special">::</span><span class="identifier">max</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="number">512</span><span class="special">,</span> <span class="comment">// under 512 is too little,</span> 204 <span class="identifier">buffer</span><span class="special">.</span><span class="identifier">capacity</span><span class="special">()</span> <span class="special">-</span> <span class="identifier">buffer</span><span class="special">.</span><span class="identifier">size</span><span class="special">()),</span> 205 <span class="identifier">std</span><span class="special">::</span><span class="identifier">min</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="number">65536</span><span class="special">,</span> <span class="comment">// and over 65536 is too much.</span> 206 <span class="identifier">buffer</span><span class="special">.</span><span class="identifier">max_size</span><span class="special">()</span> <span class="special">-</span> <span class="identifier">buffer</span><span class="special">.</span><span class="identifier">size</span><span class="special">()));</span> 207 208 <span class="comment">// Read up to bytes_to_read bytes into the dynamic buffer</span> 209 <span class="identifier">buffer</span><span class="special">.</span><span class="identifier">commit</span><span class="special">(</span><span class="identifier">sock</span><span class="special">.</span><span class="identifier">read_some</span><span class="special">(</span><span class="identifier">buffer</span><span class="special">.</span><span class="identifier">prepare</span><span class="special">(</span><span class="identifier">bytes_to_read</span><span class="special">)));</span> 210 <span class="special">}</span> 211<span class="special">}</span> 212</pre> 213<h5> 214<a name="beast.using_io.asio_refresher.h1"></a> 215 <span class="phrase"><a name="beast.using_io.asio_refresher.synchronous_i_o"></a></span><a class="link" href="asio_refresher.html#beast.using_io.asio_refresher.synchronous_i_o">Synchronous 216 I/O</a> 217 </h5> 218<p> 219 Synchronous input and output is accomplished through blocking function calls 220 that return with the result of the operation. Such operations typically cannot 221 be canceled and do not have a method for setting a timeout. The <a href="../../../../../../doc/html/boost_asio/reference/SyncReadStream.html" target="_top"><span class="emphasis"><em>SyncReadStream</em></span></a> 222 and <a href="../../../../../../doc/html/boost_asio/reference/SyncWriteStream.html" target="_top"><span class="emphasis"><em>SyncWriteStream</em></span></a> 223 concepts define requirements for <span class="emphasis"><em>synchronous streams</em></span>: 224 a portable I/O abstraction that transfers data using buffer sequences to 225 represent bytes and either <code class="computeroutput"><span class="identifier">error_code</span></code> 226 or an exception to report any failures. <a href="../../../../../../doc/html/boost_asio/reference/basic_stream_socket.html" target="_top"><span class="emphasis"><em>net::basic_stream_socket</em></span></a> 227 is a synchronous stream commonly used to form TCP/IP connections. User-defined 228 types which meet the requirements are possible: 229 </p> 230<pre class="programlisting"><span class="comment">// Meets the requirements of SyncReadStream</span> 231<span class="keyword">struct</span> <span class="identifier">sync_read_stream</span> 232<span class="special">{</span> 233 <span class="comment">// Returns the number of bytes read upon success, otherwise throws an exception</span> 234 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">MutableBufferSequence</span><span class="special">></span> 235 <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">read_some</span><span class="special">(</span><span class="identifier">MutableBufferSequence</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">buffers</span><span class="special">);</span> 236 237 <span class="comment">// Returns the number of bytes read successfully, sets the error code if a failure occurs</span> 238 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">MutableBufferSequence</span><span class="special">></span> 239 <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">read_some</span><span class="special">(</span><span class="identifier">MutableBufferSequence</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">buffers</span><span class="special">,</span> <span class="identifier">error_code</span><span class="special">&</span> <span class="identifier">ec</span><span class="special">);</span> 240<span class="special">};</span> 241 242<span class="comment">// Meets the requirements of SyncWriteStream</span> 243<span class="keyword">struct</span> <span class="identifier">sync_write_stream</span> 244<span class="special">{</span> 245 <span class="comment">// Returns the number of bytes written upon success, otherwise throws an exception</span> 246 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">ConstBufferSequence</span><span class="special">></span> 247 <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">write_some</span><span class="special">(</span><span class="identifier">ConstBufferSequence</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">buffers</span><span class="special">);</span> 248 249 <span class="comment">// Returns the number of bytes written successfully, sets the error code if a failure occurs</span> 250 <span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">ConstBufferSequence</span><span class="special">></span> 251 <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">write_some</span><span class="special">(</span><span class="identifier">ConstBufferSequence</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">buffers</span><span class="special">,</span> <span class="identifier">error_code</span><span class="special">&</span> <span class="identifier">ec</span><span class="special">);</span> 252<span class="special">};</span> 253</pre> 254<p> 255 A <span class="emphasis"><em>synchronous stream algorithm</em></span> is written as a function 256 template accepting a stream object meeting the named requirements for synchronous 257 reading, writing, or both. This example shows an algorithm which writes text 258 and uses exceptions to indicate errors: 259 </p> 260<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">SyncWriteStream</span><span class="special">></span> 261<span class="keyword">void</span> <span class="identifier">hello</span> <span class="special">(</span><span class="identifier">SyncWriteStream</span><span class="special">&</span> <span class="identifier">stream</span><span class="special">)</span> 262<span class="special">{</span> 263 <span class="identifier">net</span><span class="special">::</span><span class="identifier">const_buffer</span> <span class="identifier">cb</span><span class="special">(</span><span class="string">"Hello, world!"</span><span class="special">,</span> <span class="number">13</span><span class="special">);</span> 264 <span class="keyword">do</span> 265 <span class="special">{</span> 266 <span class="keyword">auto</span> <span class="identifier">bytes_transferred</span> <span class="special">=</span> <span class="identifier">stream</span><span class="special">.</span><span class="identifier">write_some</span><span class="special">(</span><span class="identifier">cb</span><span class="special">);</span> <span class="comment">// may throw</span> 267 <span class="identifier">cb</span> <span class="special">+=</span> <span class="identifier">bytes_transferred</span><span class="special">;</span> <span class="comment">// adjust the pointer and size</span> 268 <span class="special">}</span> 269 <span class="keyword">while</span> <span class="special">(</span><span class="identifier">cb</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">></span> <span class="number">0</span><span class="special">);</span> 270<span class="special">}</span> 271</pre> 272<p> 273 The same algorithm may be expressed using error codes instead of exceptions: 274 </p> 275<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">SyncWriteStream</span><span class="special">></span> 276<span class="keyword">void</span> <span class="identifier">hello</span> <span class="special">(</span><span class="identifier">SyncWriteStream</span><span class="special">&</span> <span class="identifier">stream</span><span class="special">,</span> <span class="identifier">error_code</span><span class="special">&</span> <span class="identifier">ec</span><span class="special">)</span> 277<span class="special">{</span> 278 <span class="identifier">net</span><span class="special">::</span><span class="identifier">const_buffer</span> <span class="identifier">cb</span><span class="special">(</span><span class="string">"Hello, world!"</span><span class="special">,</span> <span class="number">13</span><span class="special">);</span> 279 <span class="keyword">do</span> 280 <span class="special">{</span> 281 <span class="keyword">auto</span> <span class="identifier">bytes_transferred</span> <span class="special">=</span> <span class="identifier">stream</span><span class="special">.</span><span class="identifier">write_some</span><span class="special">(</span><span class="identifier">cb</span><span class="special">,</span> <span class="identifier">ec</span><span class="special">);</span> 282 <span class="identifier">cb</span> <span class="special">+=</span> <span class="identifier">bytes_transferred</span><span class="special">;</span> <span class="comment">// adjust the pointer and size</span> 283 <span class="special">}</span> 284 <span class="keyword">while</span> <span class="special">(</span><span class="identifier">cb</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">></span> <span class="number">0</span> <span class="special">&&</span> <span class="special">!</span> <span class="identifier">ec</span><span class="special">);</span> 285<span class="special">}</span> 286</pre> 287<h5> 288<a name="beast.using_io.asio_refresher.h2"></a> 289 <span class="phrase"><a name="beast.using_io.asio_refresher.asynchronous_i_o"></a></span><a class="link" href="asio_refresher.html#beast.using_io.asio_refresher.asynchronous_i_o">Asynchronous 290 I/O</a> 291 </h5> 292<p> 293 An asynchronous operation begins with a call to an <a href="../../../../../../doc/html/boost_asio/reference/asynchronous_operations.html" target="_top"><span class="emphasis"><em>initiating 294 function</em></span></a>, which starts the operation and returns to the 295 caller immediately. This <span class="emphasis"><em>outstanding</em></span> asynchronous operation 296 proceeds concurrently without blocking the caller. When the externally observable 297 side effects are fully established, a movable function object known as a 298 <a href="../../../../../../doc/html/boost_asio/reference/CompletionHandler.html" target="_top"><span class="emphasis"><em>completion 299 handler</em></span></a> provided in the initiating function call is queued 300 for execution with the results, which may include the error code and other 301 specific information. An asynchronous operation is said to be <span class="emphasis"><em>completed</em></span> 302 after the completion handler is queued. The code that follows shows how some 303 text may be written to a socket asynchronously, invoking a lambda when the 304 operation is complete: 305 </p> 306<pre class="programlisting"><span class="comment">// initiate an asynchronous write operation</span> 307<span class="identifier">net</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">net</span><span class="special">::</span><span class="identifier">const_buffer</span><span class="special">(</span><span class="string">"Hello, world!"</span><span class="special">,</span> <span class="number">13</span><span class="special">),</span> 308 <span class="special">[](</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">bytes_transferred</span><span class="special">)</span> 309 <span class="special">{</span> 310 <span class="comment">// this lambda is invoked when the write operation completes</span> 311 <span class="keyword">if</span><span class="special">(!</span> <span class="identifier">ec</span><span class="special">)</span> 312 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">bytes_transferred</span> <span class="special">==</span> <span class="number">13</span><span class="special">);</span> 313 <span class="keyword">else</span> 314 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cerr</span> <span class="special"><<</span> <span class="string">"Error: "</span> <span class="special"><<</span> <span class="identifier">ec</span><span class="special">.</span><span class="identifier">message</span><span class="special">()</span> <span class="special"><<</span> <span class="string">"\n"</span><span class="special">;</span> 315 <span class="special">});</span> 316<span class="comment">// meanwhile, the operation is outstanding and execution continues from here</span> 317</pre> 318<p> 319 Every completion handler (also referred to as a <a href="https://en.wikipedia.org/wiki/Continuation" target="_top"><span class="emphasis"><em>continuation</em></span></a>) 320 has both an <a href="../../../../../../doc/html/boost_asio/overview/core/allocation.html" target="_top"><span class="emphasis"><em>associated 321 allocator</em></span></a> returned by <a href="../../../../../../doc/html/boost_asio/reference/get_associated_allocator.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">get_associated_allocator</span></code></a>, 322 and an <a href="../../../../../../doc/html/boost_asio/reference/associated_executor.html" target="_top"><span class="emphasis"><em>associated 323 executor</em></span></a> returned by <a href="../../../../../../doc/html/boost_asio/reference/get_associated_executor.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">get_associated_executor</span></code></a>. 324 These associations may be specified intrusively: 325 </p> 326<pre class="programlisting"><span class="comment">// The following is a completion handler expressed</span> 327<span class="comment">// as a function object, with a nested associated</span> 328<span class="comment">// allocator and a nested associated executor.</span> 329<span class="keyword">struct</span> <span class="identifier">handler</span> 330<span class="special">{</span> 331 <span class="keyword">using</span> <span class="identifier">allocator_type</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator</span><span class="special"><</span><span class="keyword">char</span><span class="special">>;</span> 332 <span class="identifier">allocator_type</span> <span class="identifier">get_allocator</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span> 333 334 <span class="keyword">using</span> <span class="identifier">executor_type</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">io_context</span><span class="special">::</span><span class="identifier">executor_type</span><span class="special">;</span> 335 <span class="identifier">executor_type</span> <span class="identifier">get_executor</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span> 336 337 <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">beast</span><span class="special">::</span><span class="identifier">error_code</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">);</span> 338<span class="special">};</span> 339</pre> 340<p> 341 Or these associations may be specified non-intrusively, by specializing the 342 class templates <a href="../../../../../../doc/html/boost_asio/reference/associated_allocator.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">associated_allocator</span></code></a> 343 and <a href="../../../../../../doc/html/boost_asio/reference/associated_executor.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">associated_executor</span></code></a>: 344 </p> 345<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span> 346<span class="keyword">namespace</span> <span class="identifier">asio</span> <span class="special">{</span> 347 348<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">Allocator</span><span class="special">></span> 349<span class="keyword">struct</span> <span class="identifier">associated_allocator</span><span class="special"><</span><span class="identifier">handler</span><span class="special">,</span> <span class="identifier">Allocator</span><span class="special">></span> 350<span class="special">{</span> 351 <span class="keyword">using</span> <span class="identifier">type</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator</span><span class="special"><</span><span class="keyword">void</span><span class="special">>;</span> 352 353 <span class="keyword">static</span> 354 <span class="identifier">type</span> 355 <span class="identifier">get</span><span class="special">(</span><span class="identifier">handler</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">h</span><span class="special">,</span> 356 <span class="identifier">Allocator</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">alloc</span> <span class="special">=</span> <span class="identifier">Allocator</span><span class="special">{})</span> <span class="keyword">noexcept</span><span class="special">;</span> 357<span class="special">};</span> 358 359<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">Executor</span><span class="special">></span> 360<span class="keyword">struct</span> <span class="identifier">associated_executor</span><span class="special"><</span><span class="identifier">handler</span><span class="special">,</span> <span class="identifier">Executor</span><span class="special">></span> 361<span class="special">{</span> 362 <span class="keyword">using</span> <span class="identifier">type</span> <span class="special">=</span> <span class="identifier">any_io_executor</span><span class="special">;</span> 363 364 <span class="keyword">static</span> 365 <span class="identifier">type</span> 366 <span class="identifier">get</span><span class="special">(</span><span class="identifier">handler</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">h</span><span class="special">,</span> 367 <span class="identifier">Executor</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">ex</span> <span class="special">=</span> <span class="identifier">Executor</span><span class="special">{})</span> <span class="keyword">noexcept</span><span class="special">;</span> 368<span class="special">};</span> 369 370<span class="special">}</span> <span class="comment">// boost</span> 371<span class="special">}</span> <span class="comment">// asio</span> 372</pre> 373<p> 374 The function <a href="../../../../../../doc/html/boost_asio/reference/bind_executor.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">bind_executor</span></code></a> 375 may be used when the caller wants to change the executor of a completion 376 handler. 377 </p> 378<p> 379 The allocator is used by the implementation to obtain any temporary storage 380 necessary to perform the operation. Temporary allocations are always freed 381 before the completion handler is invoked. The executor is a cheaply copyable 382 object providing the algorithm used to invoke the completion handler. Unless 383 customized by the caller, a completion handler defaults to using <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator</span><span class="special"><</span><span class="keyword">void</span><span class="special">></span></code> 384 and the executor of the corresponding I/O object. 385 </p> 386<p> 387 Networking prescribes facilities to determine the context in which handlers 388 run. Every I/O object refers to an <a href="../../../../../../doc/html/boost_asio/reference/ExecutionContext.html" target="_top"><span class="emphasis"><em>ExecutionContext</em></span></a> 389 for obtaining the <a href="../../../../../../doc/html/boost_asio/reference/Executor1.html" target="_top"><span class="emphasis"><em>Executor</em></span></a> 390 instance used to invoke completion handlers. An executor determines where 391 and how completion handlers are invoked. Executors obtained from an instance 392 of <a href="../../../../../../doc/html/boost_asio/reference/io_context.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">io_context</span></code></a> 393 offer a basic guarantee: handlers will only be invoked from threads which 394 are currently calling <a href="../../../../../../doc/html/boost_asio/reference/io_context/run/overload1.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">io_context</span><span class="special">::</span><span class="identifier">run</span></code></a>. 395 </p> 396<p> 397 The <a href="../../../../../../doc/html/boost_asio/reference/AsyncReadStream.html" target="_top"><span class="emphasis"><em>AsyncReadStream</em></span></a> 398 and <a href="../../../../../../doc/html/boost_asio/reference/AsyncWriteStream.html" target="_top"><span class="emphasis"><em>AsyncWriteStream</em></span></a> 399 concepts define requirements for <span class="emphasis"><em>asynchronous streams</em></span>: 400 a portable I/O abstraction that exchanges data asynchronously using buffer 401 sequences to represent bytes and <code class="computeroutput"><span class="identifier">error_code</span></code> 402 to report any failures. An <span class="emphasis"><em>asynchronous stream algorithm</em></span> 403 is written as a templated initiating function template accepting a stream 404 object meeting the named requirements for asynchronous reading, writing, 405 or both. This example shows an algorithm which writes some text to an asynchronous 406 stream: 407 </p> 408<pre class="programlisting"><span class="keyword">template</span> <span class="special"><</span><span class="keyword">class</span> <span class="identifier">AsyncWriteStream</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">WriteHandler</span><span class="special">></span> 409<span class="keyword">void</span> <span class="identifier">async_hello</span> <span class="special">(</span><span class="identifier">AsyncWriteStream</span><span class="special">&</span> <span class="identifier">stream</span><span class="special">,</span> <span class="identifier">WriteHandler</span><span class="special">&&</span> <span class="identifier">handler</span><span class="special">)</span> 410<span class="special">{</span> 411 <span class="identifier">net</span><span class="special">::</span><span class="identifier">async_write</span> <span class="special">(</span><span class="identifier">stream</span><span class="special">,</span> 412 <span class="identifier">net</span><span class="special">::</span><span class="identifier">buffer</span><span class="special">(</span><span class="string">"Hello, world!"</span><span class="special">,</span> <span class="number">13</span><span class="special">),</span> 413 <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special"><</span><span class="identifier">WriteHandler</span><span class="special">>(</span><span class="identifier">handler</span><span class="special">));</span> 414<span class="special">}</span> 415</pre> 416<h5> 417<a name="beast.using_io.asio_refresher.h3"></a> 418 <span class="phrase"><a name="beast.using_io.asio_refresher.concurrency"></a></span><a class="link" href="asio_refresher.html#beast.using_io.asio_refresher.concurrency">Concurrency</a> 419 </h5> 420<p> 421 I/O objects such as sockets and streams <span class="bold"><strong>are not thread-safe</strong></span>. 422 Although it is possible to have more than one operation outstanding (for 423 example, a simultaneous asynchronous read and asynchronous write) the stream 424 object itself may only be accessed from one thread at a time. This means 425 that member functions such as move constructors, destructors, or initiating 426 functions must not be called concurrently. Usually this is accomplished with 427 synchronization primitives such as a <a href="https://en.cppreference.com/w/cpp/thread/mutex" target="_top"><code class="computeroutput"><span class="identifier">mutex</span></code></a>, but concurrent network programs 428 need a better way to access shared resources, since acquiring ownership of 429 a mutex could block threads from performing uncontended work. For efficiency, 430 networking adopts a model of using threads without explicit locking by requiring 431 all access to I/O objects to be performed within a <a href="../../../../../../doc/html/boost_asio/overview/core/strands.html" target="_top"><span class="emphasis"><em>strand</em></span></a>. 432 </p> 433<h5> 434<a name="beast.using_io.asio_refresher.h4"></a> 435 <span class="phrase"><a name="beast.using_io.asio_refresher.universal_model"></a></span><a class="link" href="asio_refresher.html#beast.using_io.asio_refresher.universal_model">Universal 436 Model</a> 437 </h5> 438<p> 439 Because completion handlers cause an inversion of the flow of control, sometimes 440 other methods of attaching a continuation are desired. Networking provides 441 the <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3747.pdf" target="_top"><span class="emphasis"><em>Universal 442 Model for Asynchronous Operations</em></span></a>, providing a customizable 443 means for transforming the signature of the initiating function to use other 444 types of objects and methods in place of a completion handler callback. For 445 example to call to write a string to a socket asynchronously, using a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">future</span></code> 446 to receive the number of bytes transferred thusly looks like this: 447 </p> 448<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">future</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">f</span> <span class="special">=</span> <span class="identifier">net</span><span class="special">::</span><span class="identifier">async_write</span><span class="special">(</span><span class="identifier">sock</span><span class="special">,</span> 449 <span class="identifier">net</span><span class="special">::</span><span class="identifier">const_buffer</span><span class="special">(</span><span class="string">"Hello, world!"</span><span class="special">,</span> <span class="number">13</span><span class="special">),</span> <span class="identifier">net</span><span class="special">::</span><span class="identifier">use_future</span><span class="special">);</span> 450</pre> 451<p> 452 This functionality is enabled by passing the variable <a href="../../../../../../doc/html/boost_asio/reference/use_future.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">use_future</span></code></a> 453 (of type <a href="../../../../../../doc/html/boost_asio/reference/use_future_t.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">use_future_t</span><span class="special"><></span></code></a>) in place of the completion 454 handler. The same <code class="computeroutput"><span class="identifier">async_write</span></code> 455 function overload can work with a <a href="https://en.wikipedia.org/wiki/Fiber_(computer_science)" target="_top"><span class="emphasis"><em>fiber</em></span></a> 456 launched with <a href="../../../../../../doc/html/boost_asio/reference/spawn/overload1.html" target="_top"><code class="computeroutput"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">spawn</span></code></a>: 457 </p> 458<pre class="programlisting"><span class="identifier">asio</span><span class="special">::</span><span class="identifier">spawn</span><span class="special">(</span> 459 <span class="special">[&</span><span class="identifier">sock</span><span class="special">](</span><span class="identifier">net</span><span class="special">::</span><span class="identifier">yield_context</span> <span class="identifier">yield</span><span class="special">)</span> 460 <span class="special">{</span> 461 <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">bytes_transferred</span> <span class="special">=</span> <span class="identifier">net</span><span class="special">::</span><span class="identifier">async_write</span><span class="special">(</span><span class="identifier">sock</span><span class="special">,</span> 462 <span class="identifier">net</span><span class="special">::</span><span class="identifier">const_buffer</span><span class="special">(</span><span class="string">"Hello, world!"</span><span class="special">,</span> <span class="number">13</span><span class="special">),</span> <span class="identifier">yield</span><span class="special">);</span> 463 <span class="special">(</span><span class="keyword">void</span><span class="special">)</span><span class="identifier">bytes_transferred</span><span class="special">;</span> 464 <span class="special">});</span> 465</pre> 466<p> 467 In both of these cases, an object with a specific type is used in place of 468 the completion handler, and the return value of the initiating function is 469 transformed from <code class="computeroutput"><span class="keyword">void</span></code> to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">future</span><span class="special"><</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">></span></code> or <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span></code>. 470 The handler is sometimes called a <a href="../../../../../../doc/html/boost_asio/reference/asynchronous_operations.html#boost_asio.reference.asynchronous_operations.completion_tokens_and_handlers" target="_top"><span class="emphasis"><em>CompletionToken</em></span></a> 471 when used in this context. The return type transformation is supported by 472 customization points in the initiating function signature. Here is the signature 473 for <a href="../../../../../../doc/html/boost_asio/reference/async_write/overload1.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">async_write</span></code></a>: 474 </p> 475<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span> 476 <span class="keyword">class</span> <span class="identifier">AsyncWriteStream</span><span class="special">,</span> 477 <span class="keyword">class</span> <span class="identifier">ConstBufferSequence</span><span class="special">,</span> 478 <span class="keyword">class</span> <span class="identifier">CompletionToken</span><span class="special">></span> 479<span class="keyword">auto</span> 480<span class="identifier">async_write</span><span class="special">(</span> 481 <span class="identifier">AsyncWriteStream</span><span class="special">*</span> <span class="identifier">stream</span><span class="special">,</span> <span class="comment">// references are passed as pointers</span> 482 <span class="identifier">ConstBufferSequence</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">buffers</span><span class="special">,</span> 483 <span class="identifier">CompletionToken</span><span class="special">&&</span> <span class="identifier">token</span><span class="special">)</span> <span class="comment">// a handler, or a special object.</span> 484 <span class="special">-></span> 485 <span class="keyword">typename</span> <span class="identifier">net</span><span class="special">::</span><span class="identifier">async_result</span><span class="special"><</span> <span class="comment">// return-type customization point.</span> 486 <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">decay</span><span class="special"><</span><span class="identifier">CompletionToken</span><span class="special">>::</span><span class="identifier">type</span><span class="special">,</span> <span class="comment">// type used to specialize async_result.</span> 487 <span class="keyword">void</span><span class="special">(</span><span class="identifier">error_code</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="comment">// underlying completion handler signature.</span> 488 <span class="special">>::</span><span class="identifier">return_type</span><span class="special">;</span> 489</pre> 490<p> 491 The type of the function's return value is determined by the <a href="../../../../../../doc/html/boost_asio/reference/async_result.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">async_result</span></code></a> 492 customization point, which comes with specializations for common library 493 types such as <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">future</span></code> and may also be specialized for 494 user-defined types. The body of the initiating function calls the <a href="../../../../../../doc/html/boost_asio/reference/async_inititate.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">async_initiate</span></code></a> 495 helper to capture the arguments and forward them to the specialization of 496 <code class="computeroutput"><span class="identifier">async_result</span></code>. An additional 497 "initiation function" object is provided which <code class="computeroutput"><span class="identifier">async_result</span></code> 498 may use to immediately launch the operation, or defer the launch of the operation 499 until some point in the future (this is called "lazy execution"). 500 The initiation function object receives the internal completion handler which 501 matches the signature expected by the initiating function: 502 </p> 503<pre class="programlisting"><span class="keyword">return</span> <span class="identifier">net</span><span class="special">::</span><span class="identifier">async_initiate</span><span class="special"><</span> 504 <span class="identifier">CompletionToken</span><span class="special">,</span> 505 <span class="keyword">void</span><span class="special">(</span><span class="identifier">error_code</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">)>(</span> 506 <span class="identifier">run_async_write</span><span class="special">{},</span> <span class="comment">// The "initiation" object.</span> 507 <span class="identifier">token</span><span class="special">,</span> <span class="comment">// Token must come before other arguments.</span> 508 <span class="special">&</span><span class="identifier">stream</span><span class="special">,</span> <span class="comment">// Additional captured arguments are</span> 509 <span class="identifier">buffers</span><span class="special">);</span> <span class="comment">// forwarded to the initiation object.</span> 510</pre> 511<p> 512 This transformed, internal handler is responsible for the finalizing step 513 that delivers the result of the operation to the caller. For example, when 514 using <code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">use_future</span></code> the internal handler will deliver 515 the result by calling <a href="https://en.cppreference.com/w/cpp/thread/promise/set_value" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">promise</span><span class="special">::</span><span class="identifier">set_value</span></code></a> 516 on the promise object returned by the initiating function. 517 </p> 518<h5> 519<a name="beast.using_io.asio_refresher.h5"></a> 520 <span class="phrase"><a name="beast.using_io.asio_refresher.using_networking"></a></span><a class="link" href="asio_refresher.html#beast.using_io.asio_refresher.using_networking">Using 521 Networking</a> 522 </h5> 523<p> 524 Most library stream algorithms require a <a href="../../../../../../doc/html/boost_asio/reference/ip__tcp/socket.html" target="_top"><code class="computeroutput"><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span></code></a>, 525 <a href="../../../../../../doc/html/boost_asio/reference/ssl__stream.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">ssl</span><span class="special">::</span><span class="identifier">stream</span></code></a>, 526 or other <a class="link" href="../concepts/streams.html" title="Streams"><span class="emphasis"><em>Stream</em></span></a> 527 object that has already established communication with a remote peer. This 528 example is provided as a reminder of how to work with sockets: 529 </p> 530<pre class="programlisting"><span class="comment">// The resolver is used to look up IP addresses and port numbers from a domain and service name pair</span> 531<span class="identifier">tcp</span><span class="special">::</span><span class="identifier">resolver</span> <span class="identifier">r</span><span class="special">{</span><span class="identifier">ioc</span><span class="special">};</span> 532 533<span class="comment">// A socket represents the local end of a connection between two peers</span> 534<span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span> <span class="identifier">stream</span><span class="special">{</span><span class="identifier">ioc</span><span class="special">};</span> 535 536<span class="comment">// Establish a connection before sending and receiving data</span> 537<span class="identifier">net</span><span class="special">::</span><span class="identifier">connect</span><span class="special">(</span><span class="identifier">stream</span><span class="special">,</span> <span class="identifier">r</span><span class="special">.</span><span class="identifier">resolve</span><span class="special">(</span><span class="string">"www.example.com"</span><span class="special">,</span> <span class="string">"http"</span><span class="special">));</span> 538 539<span class="comment">// At this point `stream` is a connected to a remote</span> 540<span class="comment">// host and may be used to perform stream operations.</span> 541</pre> 542<p> 543 Throughout this documentation identifiers with the following names have special 544 meaning: 545 </p> 546<div class="table"> 547<a name="beast.using_io.asio_refresher.global_variables"></a><p class="title"><b>Table 1.3. Global Variables</b></p> 548<div class="table-contents"><table class="table" summary="Global Variables"> 549<colgroup> 550<col> 551<col> 552</colgroup> 553<thead><tr> 554<th> 555 <p> 556 Name 557 </p> 558 </th> 559<th> 560 <p> 561 Description 562 </p> 563 </th> 564</tr></thead> 565<tbody> 566<tr> 567<td> 568 <p> 569 <a href="../../../../../../doc/html/boost_asio/reference/io_context.html" target="_top"><span class="bold"><strong><code class="computeroutput"><span class="identifier">ioc</span></code></strong></span></a> 570 </p> 571 </td> 572<td> 573 <p> 574 A variable of type <a href="../../../../../../doc/html/boost_asio/reference/io_context.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">io_context</span></code></a> which is running 575 on one separate thread, and upon which an <a href="../../../../../../doc/html/boost_asio/reference/executor_work_guard.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">executor_work_guard</span></code></a> object 576 has been constructed. 577 </p> 578 </td> 579</tr> 580<tr> 581<td> 582 <p> 583 <a href="../../../../../../doc/html/boost_asio/reference/ip__tcp/socket.html" target="_top"><span class="bold"><strong><code class="computeroutput"><span class="identifier">sock</span></code></strong></span></a> 584 </p> 585 </td> 586<td> 587 <p> 588 A variable of type <a href="../../../../../../doc/html/boost_asio/reference/ip__tcp/socket.html" target="_top"><code class="computeroutput"><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span></code></a> which has already 589 been connected to a remote host. 590 </p> 591 </td> 592</tr> 593<tr> 594<td> 595 <p> 596 <a href="../../../../../../doc/html/boost_asio/reference/ssl__stream.html" target="_top"><span class="bold"><strong><code class="computeroutput"><span class="identifier">ssl_sock</span></code></strong></span></a> 597 </p> 598 </td> 599<td> 600 <p> 601 A variable of type <a href="../../../../../../doc/html/boost_asio/reference/ssl__stream.html" target="_top"><code class="computeroutput"><span class="identifier">net</span><span class="special">::</span><span class="identifier">ssl</span><span class="special">::</span><span class="identifier">stream</span><span class="special"><</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">></span></code></a> 602 which is already connected and has handshaked with a remote host. 603 </p> 604 </td> 605</tr> 606<tr> 607<td> 608 <p> 609 <a class="link" href="../ref/boost__beast__websocket__stream.html" title="websocket::stream"><span class="bold"><strong><code class="computeroutput"><span class="identifier">ws</span></code></strong></span></a> 610 </p> 611 </td> 612<td> 613 <p> 614 A variable of type <a class="link" href="../ref/boost__beast__websocket__stream.html" title="websocket::stream"><code class="computeroutput"><span class="identifier">websocket</span><span class="special">::</span><span class="identifier">stream</span><span class="special"><</span><span class="identifier">tcp</span><span class="special">::</span><span class="identifier">socket</span><span class="special">></span></code></a> 615 which is already connected with a remote host. 616 </p> 617 </td> 618</tr> 619</tbody> 620</table></div> 621</div> 622<br class="table-break"> 623</div> 624<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> 625<td align="left"></td> 626<td align="right"><div class="copyright-footer">Copyright © 2016-2019 Vinnie 627 Falco<p> 628 Distributed under the Boost Software License, Version 1.0. (See accompanying 629 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>) 630 </p> 631</div></td> 632</tr></table> 633<hr> 634<div class="spirit-nav"> 635<a accesskey="p" href="../using_io.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../using_io.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="stream_types.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a> 636</div> 637</body> 638</html> 639