This commit is contained in:
Vinnie Falco
2019-01-17 17:04:33 -08:00
parent 03bf9144b7
commit 4fcd6601b3
3 changed files with 172 additions and 67 deletions

View File

@@ -2,6 +2,7 @@ Version 204
* Add basic_timeout_stream * Add basic_timeout_stream
* Unit test macros use the global suite * Unit test macros use the global suite
* Doc work
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

View File

@@ -69,6 +69,7 @@
[def __ConstBufferSequence__ [@boost:/doc/html/boost_asio/reference/ConstBufferSequence.html ['ConstBufferSequence]]] [def __ConstBufferSequence__ [@boost:/doc/html/boost_asio/reference/ConstBufferSequence.html ['ConstBufferSequence]]]
[def __EndpointSequence__ [@boost:/doc/html/boost_asio/reference/EndpointSequence.html ['EndpointSequence]]] [def __EndpointSequence__ [@boost:/doc/html/boost_asio/reference/EndpointSequence.html ['EndpointSequence]]]
[def __Executor__ [@boost:/doc/html/boost_asio/reference/Executor1.html ['Executor]]] [def __Executor__ [@boost:/doc/html/boost_asio/reference/Executor1.html ['Executor]]]
[def __ExecutionContext__ [@boost:/doc/html/boost_asio/reference/ExecutionContext.html ['ExecutionContext]]]
[def __Handler__ [@boost:/doc/html/boost_asio/reference/Handler.html ['Handler]]] [def __Handler__ [@boost:/doc/html/boost_asio/reference/Handler.html ['Handler]]]
[def __IteratorConnectHandler__ [@boost:/doc/html/boost_asio/reference/IteratorConnectHandler.html ['IteratorConnectHandler]]] [def __IteratorConnectHandler__ [@boost:/doc/html/boost_asio/reference/IteratorConnectHandler.html ['IteratorConnectHandler]]]
[def __MutableBufferSequence__ [@boost:/doc/html/boost_asio/reference/MutableBufferSequence.html ['MutableBufferSequence]]] [def __MutableBufferSequence__ [@boost:/doc/html/boost_asio/reference/MutableBufferSequence.html ['MutableBufferSequence]]]

View File

@@ -14,37 +14,35 @@ This section reviews networking concepts as a reminder and guide for further
learning. learning.
A A
['network] [@https://en.wikipedia.org/wiki/Computer_network ['network]]
allows programs located anywhere to exchange information after opting-in allows programs located anywhere to exchange information after opting-in
to communications by establishing a to communications by establishing a
['connection]. [@https://en.wikipedia.org/wiki/Data_link ['connection]].
Data is reliably transferred on a connection in either direction (full-duplex) Data is reliably transferred on a connection in either direction
([@https://en.wikipedia.org/wiki/Duplex_(telecommunications) ['full-duplex]])
with bytes arriving in the same order they were sent. These connections, along with bytes arriving in the same order they were sent. These connections, along
with the objects and types used to represent them, are collectively termed with the objects and types used to represent them, are collectively termed
['streams]. [link beast.concepts.streams ['streams]].
The The
['internet] [@https://en.wikipedia.org/wiki/Internet ['internet]]
is a global network of interconnected computers which exchange information is a global network of interconnected computers which exchange information
using a variety of standardized communication protocols. The most popular using a variety of standardized communication protocols. The most popular
protocol is protocol is
['TCP/IP], [@https://en.wikipedia.org/wiki/Transmission_Control_Protocol ['TCP/IP]],
which this library relies on exclusively. The protocol takes care of the which this library relies on exclusively. The protocol takes care of the
low level details so that applications see a low level details so that applications see a
['stream], ['stream], which is the reliable, full-duplex connection carrying the ordered
which is the reliable, full-duplex connection carrying the ordered set set of bytes described above.
of bytes described above.
A vendor supplies a program called a A vendor supplies a program called a
['driver], [@https://en.wikipedia.org/wiki/Device_driver ['device driver]],
enabling networking hardware such as an enabling networking hardware such as an
['ethernet adaptor] [@https://en.wikipedia.org/wiki/Network_interface_controller ['ethernet adaptor]]
to talk to the operating system. The OS in turn permits running programs to to talk to the operating system. This in turn permits running programs to
interact with networking using various flavors of interfaces, such as: interact with networking using various flavors of interfaces such as
[@https://en.wikipedia.org/wiki/Berkeley_sockets ['Berkeley sockets]] or
* Berkeley sockets [@https://en.wikipedia.org/wiki/Winsock ['Windows Sockets 2]] ("Winsock").
* POSIX sockets
* Windows Sockets 2 ("Winsock")
C++ Networking, represented by __NetTS__ and __Asio__, provides another layer C++ Networking, represented by __NetTS__ and __Asio__, provides another layer
of abstraction with features such as: of abstraction with features such as:
@@ -57,81 +55,179 @@ of abstraction with features such as:
These concepts enable generic programming so that higher levels of abstraction These concepts enable generic programming so that higher levels of abstraction
may be composed to arbitrary degree. In fact, the interfaces and concepts may be composed to arbitrary degree. In fact, the interfaces and concepts
offered by networking are best described as providing support for general offered by networking are best described as providing support for general
input and output algorithms ("I/O"), including TCP/IP. [@https://en.wikipedia.org/wiki/Input/output ['input/output]] ("I/O")
algorithms, including networking.
[heading Buffers] [heading Buffers]
A A
['buffer] [@https://en.wikipedia.org/wiki/Data_buffer ['buffer]]
holds a contiguous sequence of bytes used to perform reads or writes on an holds a contiguous sequence of bytes used when reading or writing data with
['I/O object]. objects that perform I/O.
The networking types __const_buffer__ and __mutable_buffer__ represent The networking types __const_buffer__ and __mutable_buffer__ represent
these memory regions as type-safe pointer/size pairs. The concepts these memory regions as type-safe pointer/size pairs, as shown below:
__ConstBufferSequence__ and __MutableBufferSequence__ are bidirectional ```
net::const_buffer cb("Hello, world!", 13);
assert(string_view(reinterpret_cast<char const*>(cb.data()), cb.size()) == "Hello, world!");
char storage[13];
net::mutable_buffer mb(bytes, sizeof(storage));
std::memcpy(mb.data(), cb.data(), mb.size());
assert(string_view(reinterpret_cast<char const*>(mb.data()), mb.size()) == "Hello, world!");
```
The concepts
__ConstBufferSequence__ and __MutableBufferSequence__ describe bidirectional
ranges whose value type is convertible to __const_buffer__ and ranges whose value type is convertible to __const_buffer__ and
__mutable_buffer__ respectively. Buffer sequences may be used to transact __mutable_buffer__ respectively. Buffer sequences may be used to transact
in multiple buffers in a single function call. These types are non-owning; in multiple buffers in a single function call, a technique sometimes
copying a buffer or buffer sequences only creates a shallow reference, referred to as
it does allocate a copy of the contents. [@https://en.wikipedia.org/wiki/Vectored_I/O ['scatter/gather I/O]].
Buffer and buffer sequence types are non-owning; creating a copy only results
in a shallow reference and not a duplicate of the underlying memory. These
are all examples of buffer sequences:
```
net::const_buffer b1;
net::mutable_buffer b2;
std::array<net::const_buffer, 3> b3;
```
Buffers described thus far may not be resized. The __DynamicBuffer__ The __DynamicBuffer__ concept defines a buffer container which may be
concept defines a storage type whose size can change. Beast uses resized using a well defined interface. Beast and networking use dynamic
dynamic buffers in interfaces where the amount of storage required buffers when the amount of storage required to perform an operation is
to complete an operation is not known ahead of time. not known ahead of time, such as when reading a complete HTTP message.
[heading Synchronous I/O]
Synchronous input and output is accomplished through blocking function
calls that provide the complete results of the operation upon returning.
Such operations typically cannot be canceled and do not have a method for
setting a timeout. The __SyncReadStream__ and __SyncWriteStream__ concepts
define requirements for
['synchronous streams],
permitting portable exchange of data using buffer sequence abstractions
to represent bytes and either `error_code` or exceptions to describe any
failures.
[/ [heading Synchronous I/O] ] A
['synchronous stream algorithm]
is written as a function template accepting a stream object meeting the
named requirements for synchronous reading, writing, or both. This generic
example shows how some text might be written synchronously to a stream,
using exceptions to indicate errors:
```
template <class SyncWriteStream>
void hello (SyncWriteStream& stream)
{
net::const_buffer buffer("Hello, world!", 13);
do
{
auto bytes_transferred = stream.write_some(buffer); // may throw
buffer += bytes_transferred; // adjust the pointer and size
}
while (buffer.size() > 0);
}
```
The same function may be written to use error codes instead of exceptions:
```
template <class SyncWriteStream>
void hello (SyncWriteStream& stream, error_code& ec)
{
net::const_buffer buffer("Hello, world!", 13);
do
{
auto bytes_transferred = stream.write_some(buffer, ec);
buffer += bytes_transferred; // adjust the pointer and size
}
while (buffer.size() > 0 && ! ec);
}
```
[heading Asynchronous I/O] [heading Asynchronous I/O]
An asynchronous operation starts with a call to an An asynchronous operation starts with a call to an
['initiating function], [@boost:/doc/html/boost_asio/reference/asynchronous_operations.html ['initiating function]],
whose name begins with the prefix `async_`. The initating function which starts the operation and returns to the caller immediately. This
allocates memory as needed, possibly capturing arguments, then ['outstanding]
launches the operation before returning to the caller immediately. asynchronous operation continues to make progress concurrently without
The operation is now blocking. When the externally observable side effects are fully established,
['outstanding], a movable function object known as a
making progress without blocking the caller. [@boost:/doc/html/boost_asio/reference/CompletionHandler.html ['completion handler]]
provided in the initiating function call is then queued for execution to
receive the results of the operation, which may include the error code and other
specific information. The operation is considered
['completed]
when the completion handler has been queued for execution with the results.
The result of the operation is Every completion handler (also referred to as a
['available] ['continuation]
when the externally observable side effects are fully established. since it represents a continuation of the flow of control that starts
A movable function object known as a with the initiating function call) has an
['completion handler] [@boost:/doc/html/boost_asio/overview/core/allocation.html ['associated allocator]].
(provided to the initiating function) is then invoked with the result. Temporary storage obtained using the associated allocator [*must] be deallocated
A completion handler is also referred to as a before the completion handler is invoked.
['continuation], Each completion handler also has an
since it represents a continuation of the flow of execution that ['associated executor].
started from the initiating function call. An executor is a cheaply copyable object that provides an algorithm for
Temporary storage required to perform an operation may be allocated using invoking nullary function objects.
the completion handler's
['associated allocator],
which can optionally be suggested by the caller. These allocations
[*must] be freed before the completion handler is invoked.
Networking provides well-defined facilities for determining the context Networking prescribes facilities to determine the context
where handlers run. Every I/O object is associated with an where handlers run. Every I/O object is associated with an
['ExecutionContext], __ExecutionContext__,
which permits implementations to store private per-context data and which permits implementations to store private per-context data and
also supplies instances of its also supplies instances of its
['Executor] that determines where and how a handler is invoked in the __Executor__
exection context. Instances of __io_context__ offer the basic execution that determines where and how a handler is invoked in the
guarantee: handlers will only be executed from caller-provided threads exection context. Instances of __io_context__ offer a basic guarantee:
which are currently invoking handlers will only be executed from caller-provided threads which are
currently invoking
[@boost:/doc/html/boost_asio/reference/io_context/run/overload1.html `net::io_context::run`]. [@boost:/doc/html/boost_asio/reference/io_context/run/overload1.html `net::io_context::run`].
An An
['associated executor] [@boost:/doc/html/boost_asio/overview/core/strands.html ['associated executor]]
is defined for every completion handler, which defaults to the I/O is defined for every completion handler, defaulting to the executor of the
object's executor. The executor for a completion handler may be target I/O object. The executor for a completion handler may be customized,
customized, for example by choosing a __strand__. A strand provides an for example by choosing a __strand__.
additional execution guarantee: function objects submitted to the strand
are never executed concurrently by the underlying executor. Strands permit The __AsyncReadStream__ and __AsyncWriteStream__ concepts define requirements for
concurrent asynchronous applications to be developed which do not require ['asynchronous streams],
explicit locking. permitting portable exchange of data asynchronously using buffer sequence
abstractions to represent bytes and `error_code` to describe any failures.
An
['asynchronous stream algorithm]
is written as a templated initiating function template which accepts a stream
object meeting the named requirements for asynchronous reading, writing, or
both. The signature for the initiating function includes a
['completion token],
which is a generalization of completion handlers permitting user-defined
types such as futures or coroutines to be substituted as the mechanism by
which the results of the asynchronous operation are delivered. The following
statements all call the same function to asynchronously read data from a
stream, but use a different method for receiving the results:
```
net::async_read(sock, buffer,
[error_code ec, std::size_t bytes_transferred]
{
if(ec)
std::cout << "Error: " << ec.message() << "\n";
```
The system
for customizing the return type of initiating functions and obtaining the
actual completion handler from a completion token is known as the
[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3747.pdf ['Universal Model for Asynchronous Operations]] (N3747).
This generic example shows the signature for an initiating function to write
some text to a stream:
```
template <class AsyncWriteStream, class WriteHandler>
auto async_hello (AsyncWriteStream& stream, WriteHandler&& handler);
```
[/ [/
[heading Concurrency Without Locking] [heading Concurrency Without Locking]
@@ -143,10 +239,17 @@ explicit locking.
[heading Universal Asynchronous Model] [heading Universal Asynchronous Model]
A strand provides an additional execution
guarantee: function objects submitted to the strand are never executed
concurrently by the underlying executor. Strands permit concurrent asynchronous
applications to be developed which
[@boost:/doc/html/boost_asio/overview/core/strands.html use threads without explicit locking].
The use of invocable function objects The use of invocable function objects
] ]
[heading Using Networking]
[warning [warning
Beast does not manage sockets, make outgoing connections, Beast does not manage sockets, make outgoing connections,