1_refresher.qbk 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. [/
  2. Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
  3. Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. Official repository: https://github.com/boostorg/beast
  6. ]
  7. [section:asio_refresher Refresher]
  8. To use Beast effectively, a prior understanding of Networking is required.
  9. This section reviews these concepts as a reminder and guide for further
  10. learning.
  11. A
  12. [@https://en.wikipedia.org/wiki/Computer_network ['network]]
  13. allows programs located anywhere to exchange information after opting-in
  14. to communications by establishing a
  15. [@https://en.wikipedia.org/wiki/Data_link ['connection]].
  16. Data may be reliably transferred across a connection in both directions
  17. ([@https://en.wikipedia.org/wiki/Duplex_(telecommunications) ['full-duplex]])
  18. with bytes arriving in the same order they were sent. These connections, along
  19. with the objects and types used to represent them, are collectively termed
  20. [link beast.concepts.streams ['streams]]. The computer or device attached
  21. to the network is called a
  22. [@https://en.wikipedia.org/wiki/Host_(network) ['host]], and the
  23. program on the other end of an established connection is called a
  24. [@https://en.wikipedia.org/wiki/Peer-to-peer ['peer]].
  25. The
  26. [@https://en.wikipedia.org/wiki/Internet ['internet]]
  27. is a global network of interconnected computers that use a variety of
  28. standardized communication protocols to exchange information. The most
  29. popular protocol is
  30. [@https://en.wikipedia.org/wiki/Transmission_Control_Protocol ['TCP/IP]],
  31. which this library relies on exclusively. The protocol takes care of the
  32. low level details so that applications see a
  33. ['stream], which is the reliable, full-duplex connection carrying the ordered
  34. set of bytes described above. A
  35. [@https://en.wikipedia.org/wiki/Server_(computing) ['server]]
  36. is a powerful, always-on host at a well-known network name or network address
  37. which provides data services. A
  38. [@https://en.wikipedia.org/wiki/Client_(computing) ['client]]
  39. is a transient peer which connects to a server to exchange data, and goes
  40. offline.
  41. A vendor supplies a program called a
  42. [@https://en.wikipedia.org/wiki/Device_driver ['device driver]],
  43. enabling networking hardware such as an
  44. [@https://en.wikipedia.org/wiki/Network_interface_controller ['ethernet adaptor]]
  45. to talk to the operating system. This in turn permits running programs to
  46. interact with networking using various flavors of interfaces such as
  47. [@https://en.wikipedia.org/wiki/Berkeley_sockets ['Berkeley sockets]] or
  48. [@https://en.wikipedia.org/wiki/Winsock ['Windows Sockets 2]] ("Winsock").
  49. Networking in C++, represented by __Asio__,
  50. [@https://think-async.com/Asio/ Asio], and
  51. __NetTS__, provides a layer of abstraction to interact portably with the
  52. operating system facilities for not just networking but general
  53. [@https://en.wikipedia.org/wiki/Input/output ['input/output]] ("I/O").
  54. [/-----------------------------------------------------------------------------]
  55. [heading Buffers]
  56. A
  57. [@https://en.wikipedia.org/wiki/Data_buffer ['buffer]]
  58. holds a contiguous sequence of bytes used when performing I/O.
  59. The types
  60. [@boost:/doc/html/boost_asio/reference/const_buffer.html `net::const_buffer`]
  61. and
  62. [@boost:/doc/html/boost_asio/reference/mutable_buffer.html `net::mutable_buffer`]
  63. represent these memory regions as type-safe pointer/size pairs:
  64. [code_core_1_refresher_1s]
  65. [tip
  66. `const_buffer` and `mutable_buffer` are preferred over `std::span<byte>`
  67. and `span<byte const>` because
  68. [@https://en.cppreference.com/w/cpp/container/span `std::span`]
  69. does too much. It not only
  70. type-erases the original pointer but also recasts it to a pointer-to-byte.
  71. The operating system doesn't care about this, but if a user wants to send
  72. and receive an array of some other type, presenting it as an array of bytes
  73. which supports bitwise operations is unnecessary. Custom buffer types also
  74. enable implementations to provide targeted features such as
  75. [@boost:/doc/html/boost_asio/overview/core/buffers.html#boost_asio.overview.core.buffers.buffer_debugging ['buffer debugging]]
  76. without changing the more general vocabulary types.
  77. ]
  78. The concepts
  79. __ConstBufferSequence__ and __MutableBufferSequence__ describe bidirectional
  80. ranges whose value type is convertible to `const_buffer` and
  81. `mutable_buffer` respectively. These sequences allow transacting with
  82. multiple buffers in a single function call, a technique called
  83. [@https://en.wikipedia.org/wiki/Vectored_I/O ['scatter/gather I/O]].
  84. Buffers and buffer sequences are non-owning; copies produce shallow references
  85. and not duplicates of the underlying memory. Each of these statements declares
  86. a buffer sequence:
  87. [code_core_1_refresher_2s]
  88. The functions
  89. [@boost:/doc/html/boost_asio/reference/buffer_size.html `net::buffer_size`] and
  90. [@boost:/doc/html/boost_asio/reference/buffer_copy.html `net::buffer_copy`]
  91. determine the total number of bytes in a buffer sequence, and transfer some
  92. or all of bytes from one buffer sequence to another respectively. The
  93. function `buffer_size` is a customization point: user defined overloads
  94. in foreign namespaces are possible, and callers should invoke `buffer_size`
  95. without namespace qualification. The functions
  96. [@boost:/doc/html/boost_asio/reference/buffer_sequence_begin.html `net::buffer_sequence_begin`] and
  97. [@boost:/doc/html/boost_asio/reference/buffer_sequence_end.html `net::buffer_sequence_end`]
  98. are used to obtain a pair of iterators for traversing the sequence.
  99. Beast provides a set of buffer sequence types and algorithms such as
  100. [link beast.ref.boost__beast__buffers_cat `buffers_cat`],
  101. [link beast.ref.boost__beast__buffers_front `buffers_front`],
  102. [link beast.ref.boost__beast__buffers_prefix `buffers_prefix`],
  103. [link beast.ref.boost__beast__buffers_range `buffers_range`], and
  104. [link beast.ref.boost__beast__buffers_suffix `buffers_suffix`].
  105. This example returns the bytes in a buffer sequence as a string:
  106. [code_core_1_refresher_1]
  107. The __DynamicBuffer__ concept defines a resizable buffer sequence interface.
  108. Algorithms may be expressed in terms of dynamic buffers when the memory
  109. requirements are not known ahead of time, for example when reading an
  110. HTTP message from a stream.
  111. Beast provides a well-rounded collection of dynamic buffer types such as
  112. [link beast.ref.boost__beast__buffers_adaptor `buffers_adaptor`],
  113. [link beast.ref.boost__beast__flat_buffer `flat_buffer`],
  114. [link beast.ref.boost__beast__multi_buffer `multi_buffer`], and
  115. [link beast.ref.boost__beast__static_buffer `static_buffer`].
  116. The following function reads data from a
  117. [link beast.ref.boost__beast__tcp_stream `tcp_stream`]
  118. into a dynamic buffer until it encountering a newline character, using
  119. [@boost:/doc/html/boost_asio/reference/buffers_iterator.html `net::buffers_iterator`]
  120. to treat the contents of the buffer as a range of characters:
  121. [code_core_1_refresher_2]
  122. [/-----------------------------------------------------------------------------]
  123. [heading Synchronous I/O]
  124. Synchronous input and output is accomplished through blocking function
  125. calls that return with the result of the operation. Such operations typically
  126. cannot be canceled and do not have a method for setting a timeout. The
  127. __SyncReadStream__ and __SyncWriteStream__ concepts define requirements for
  128. ['synchronous streams]:
  129. a portable I/O abstraction that transfers data using buffer sequences to
  130. represent bytes and either `error_code` or an exception to report any
  131. failures.
  132. [@boost:/doc/html/boost_asio/reference/basic_stream_socket.html ['net::basic_stream_socket]]
  133. is a synchronous stream commonly used to form TCP/IP connections.
  134. User-defined types which meet the requirements are possible:
  135. [code_core_1_refresher_3]
  136. A
  137. ['synchronous stream algorithm]
  138. is written as a function template accepting a stream object meeting the
  139. named requirements for synchronous reading, writing, or both. This example
  140. shows an algorithm which writes text and uses exceptions to indicate errors:
  141. [code_core_1_refresher_4]
  142. The same algorithm may be expressed using error codes instead of exceptions:
  143. [code_core_1_refresher_5]
  144. [/-----------------------------------------------------------------------------]
  145. [heading Asynchronous I/O]
  146. An asynchronous operation begins with a call to an
  147. [@boost:/doc/html/boost_asio/reference/asynchronous_operations.html ['initiating function]],
  148. which starts the operation and returns to the caller immediately. This
  149. ['outstanding]
  150. asynchronous operation proceeds concurrently without blocking the caller.
  151. When the externally observable side effects are fully established, a movable
  152. function object known as a
  153. [@boost:/doc/html/boost_asio/reference/CompletionHandler.html ['completion handler]]
  154. provided in the initiating function call is queued for execution with the
  155. results, which may include the error code and other specific information.
  156. An asynchronous operation is said to be
  157. ['completed]
  158. after the completion handler is queued. The code that follows shows how some
  159. text may be written to a socket asynchronously, invoking a lambda when the
  160. operation is complete:
  161. [code_core_1_refresher_3s]
  162. Every completion handler (also referred to as a
  163. [@https://en.wikipedia.org/wiki/Continuation ['continuation]])
  164. has both an
  165. [@boost:/doc/html/boost_asio/overview/core/allocation.html ['associated allocator]]
  166. returned by
  167. [@boost:/doc/html/boost_asio/reference/get_associated_allocator.html `net::get_associated_allocator`],
  168. and an
  169. [@boost:/doc/html/boost_asio/reference/associated_executor.html ['associated executor]]
  170. returned by
  171. [@boost:/doc/html/boost_asio/reference/get_associated_executor.html `net::get_associated_executor`].
  172. These associations may be specified intrusively:
  173. [code_core_1_refresher_6]
  174. Or these associations may be specified non-intrusively, by specializing
  175. the class templates
  176. [@boost:/doc/html/boost_asio/reference/associated_allocator.html `net::associated_allocator`]
  177. and
  178. [@boost:/doc/html/boost_asio/reference/associated_executor.html `net::associated_executor`]:
  179. [code_core_1_refresher_7]
  180. The function
  181. [@boost:/doc/html/boost_asio/reference/bind_executor.html `net::bind_executor`]
  182. may be used when the caller wants to change the executor of a completion
  183. handler.
  184. The allocator is used by the implementation to obtain any temporary storage
  185. necessary to perform the operation. Temporary allocations are always freed
  186. before the completion handler is invoked. The executor is a cheaply copyable
  187. object providing the algorithm used to invoke the completion handler. Unless
  188. customized by the caller, a completion handler defaults to using
  189. `std::allocator<void>` and the executor of the corresponding I/O object.
  190. Networking prescribes facilities to determine the context in which
  191. handlers run. Every I/O object refers to an __ExecutionContext__ for
  192. obtaining the __Executor__ instance used to invoke completion handlers.
  193. An executor determines where and how completion handlers are invoked.
  194. Executors obtained from an instance of __io_context__ offer a basic guarantee:
  195. handlers will only be invoked from threads which are currently calling
  196. [@boost:/doc/html/boost_asio/reference/io_context/run/overload1.html `net::io_context::run`].
  197. The __AsyncReadStream__ and __AsyncWriteStream__ concepts define requirements for
  198. ['asynchronous streams]:
  199. a portable I/O abstraction that exchanges data asynchronously using buffer
  200. sequences to represent bytes and `error_code` to report any failures. An
  201. ['asynchronous stream algorithm]
  202. is written as a templated initiating function template accepting a stream
  203. object meeting the named requirements for asynchronous reading, writing, or
  204. both. This example shows an algorithm which writes some text to an
  205. asynchronous stream:
  206. [code_core_1_refresher_8]
  207. [/-----------------------------------------------------------------------------]
  208. [heading Concurrency]
  209. I/O objects such as sockets and streams [*are not thread-safe]. Although
  210. it is possible to have more than one operation outstanding (for example,
  211. a simultaneous asynchronous read and asynchronous write) the stream object
  212. itself may only be accessed from one thread at a time. This means that
  213. member functions such as move constructors, destructors, or initiating
  214. functions must not be called concurrently. Usually this is accomplished
  215. with synchronization primitives such as a
  216. [@https://en.cppreference.com/w/cpp/thread/mutex `mutex`],
  217. but concurrent network programs need a better way to access shared resources,
  218. since acquiring ownership of a mutex could block threads from performing
  219. uncontended work. For efficiency, networking adopts a model of using threads
  220. without explicit locking by requiring all access to I/O objects to be
  221. performed within a
  222. [@boost:/doc/html/boost_asio/overview/core/strands.html ['strand]].
  223. [/-----------------------------------------------------------------------------]
  224. [heading Universal Model]
  225. Because completion handlers cause an inversion of the flow of control,
  226. sometimes other methods of attaching a continuation are desired. Networking
  227. provides the
  228. [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3747.pdf ['Universal Model for Asynchronous Operations]],
  229. providing a customizable means for transforming the signature of the initiating
  230. function to use other types of objects and methods in place of a completion
  231. handler callback. For example to call to write a string to a socket
  232. asynchronously, using a `std::future` to receive the number of bytes transferred
  233. thusly looks like this:
  234. [code_core_1_refresher_4s]
  235. This functionality is enabled by passing the variable
  236. [@boost:/doc/html/boost_asio/reference/use_future.html `net::use_future`]
  237. (of type
  238. [@boost:/doc/html/boost_asio/reference/use_future_t.html `net::use_future_t<>`])
  239. in place of the completion handler. The same `async_write` function overload
  240. can work with a
  241. [@https://en.wikipedia.org/wiki/Fiber_(computer_science) ['fiber]]
  242. launched with
  243. [@boost:/doc/html/boost_asio/reference/spawn/overload1.html `asio::spawn`]:
  244. [code_core_1_refresher_5s]
  245. In both of these cases, an object with a specific type is used in place of
  246. the completion handler, and the return value of the initiating function
  247. is transformed from `void` to `std::future<std::size_t>` or `std::size_t`.
  248. The handler is sometimes called a
  249. __CompletionToken__
  250. when used in this context. The return type transformation is supported by
  251. customization points in the initiating function signature. Here is the
  252. signature for
  253. [@boost:/doc/html/boost_asio/reference/async_write/overload1.html `net::async_write`]:
  254. [code_core_1_refresher_9]
  255. The type of the function's return value is determined by the
  256. [@boost:/doc/html/boost_asio/reference/async_result.html `net::async_result`]
  257. customization point, which comes with specializations for common library
  258. types such as `std::future` and may also be specialized for user-defined
  259. types. The body of the initiating function calls the
  260. [@boost:/doc/html/boost_asio/reference/async_inititate.html `net::async_initiate`]
  261. helper to capture the arguments and forward them to the specialization of
  262. `async_result`. An additional "initiation function" object is provided which
  263. `async_result` may use to immediately launch the operation, or defer the launch
  264. of the operation until some point in the future (this is called "lazy
  265. execution"). The initiation function object receives the internal completion
  266. handler which matches the signature expected by the initiating function:
  267. [code_core_1_refresher_10]
  268. This transformed, internal handler is responsible for the finalizing step that
  269. delivers the result of the operation to the caller. For example, when using
  270. `net::use_future` the internal handler will deliver the result by calling
  271. [@https://en.cppreference.com/w/cpp/thread/promise/set_value `std::promise::set_value`]
  272. on the promise object returned by the initiating function.
  273. [/-----------------------------------------------------------------------------]
  274. [heading Using Networking]
  275. Most library stream algorithms require a __socket__, __ssl_stream__, or
  276. other __Stream__ object that has already established communication with
  277. a remote peer. This example is provided as a reminder of how to work with
  278. sockets:
  279. [snippet_core_2]
  280. Throughout this documentation identifiers with the following names have
  281. special meaning:
  282. [table Global Variables
  283. [[Name][Description]]
  284. [[
  285. [@boost:/doc/html/boost_asio/reference/io_context.html [*`ioc`]]
  286. ][
  287. A variable of type __io_context__ which is running on one separate thread,
  288. and upon which an __executor_work_guard__ object has been constructed.
  289. ]]
  290. [[
  291. [@boost:/doc/html/boost_asio/reference/ip__tcp/socket.html [*`sock`]]
  292. ][
  293. A variable of type
  294. [@boost:/doc/html/boost_asio/reference/ip__tcp/socket.html `tcp::socket`]
  295. which has already been connected to a remote host.
  296. ]]
  297. [[
  298. [@boost:/doc/html/boost_asio/reference/ssl__stream.html [*`ssl_sock`]]
  299. ][
  300. A variable of type
  301. [@boost:/doc/html/boost_asio/reference/ssl__stream.html `net::ssl::stream<tcp::socket>`]
  302. which is already connected and has handshaked with a remote host.
  303. ]]
  304. [[
  305. [link beast.ref.boost__beast__websocket__stream [*`ws`]]
  306. ][
  307. A variable of type
  308. [link beast.ref.boost__beast__websocket__stream `websocket::stream<tcp::socket>`]
  309. which is already connected with a remote host.
  310. ]]
  311. ]
  312. [endsect]