12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568 |
- //
- // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
- //
- // Distributed under the Boost Software License, Version 1.0. (See accompanying
- // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
- //
- // Official repository: https://github.com/boostorg/beast
- //
- #ifndef BHO_BEAST_CORE_BASIC_STREAM_HPP
- #define BHO_BEAST_CORE_BASIC_STREAM_HPP
- #include <asio2/bho/beast/core/detail/config.hpp>
- #include <asio2/bho/beast/core/detail/stream_base.hpp>
- #include <asio2/bho/beast/core/error.hpp>
- #include <asio2/bho/beast/core/rate_policy.hpp>
- #include <asio2/bho/beast/core/role.hpp>
- #include <asio2/bho/beast/core/stream_traits.hpp>
- #include <asio/async_result.hpp>
- #include <asio/basic_stream_socket.hpp>
- #include <asio/connect.hpp>
- #include <asio/executor.hpp>
- #include <asio/is_executor.hpp>
- #include <asio2/bho/core/empty_value.hpp>
- #include <asio2/bho/config/workaround.hpp>
- #include <chrono>
- #include <limits>
- #include <memory>
- #if ! BHO_BEAST_DOXYGEN
- #ifdef ASIO_STANDALONE
- namespace asio {
- #else
- namespace boost::asio {
- #endif
- namespace ssl {
- template<typename> class stream;
- } // ssl
- } // asio
- #endif
- namespace bho {
- namespace beast {
- /** A stream socket wrapper with timeouts, an executor, and a rate limit policy.
- This stream wraps a `net::basic_stream_socket` to provide
- the following features:
- @li An <em>Executor</em> may be associated with the stream, which will
- be used to invoke any completion handlers which do not already have
- an associated executor. This achieves support for
- <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1322r0.html">[P1322R0] Networking TS enhancement to enable custom I/O executors</a>.
- @li Timeouts may be specified for each logical asynchronous operation
- performing any reading, writing, or connecting.
- @li A <em>RatePolicy</em> may be associated with the stream, to implement
- rate limiting through the policy's interface.
- Although the stream supports multiple concurrent outstanding asynchronous
- operations, the stream object is not thread-safe. The caller is responsible
- for ensuring that the stream is accessed from only one thread at a time.
- This includes the times when the stream, and its underlying socket, are
- accessed by the networking implementation. To meet this thread safety
- requirement, all asynchronous operations must be performed by the stream
- within the same implicit strand (only one thread `net::io_context::run`)
- or within the same explicit strand, such as an instance of `net::strand`.
- Completion handlers with explicit associated executors (such as those
- arising from use of `net::bind_executor`) will be invoked by the stream
- using the associated executor. Otherwise, the completion handler will
- be invoked by the executor associated with the stream upon construction.
- The type of executor used with this stream must meet the following
- requirements:
- @li Function objects submitted to the executor shall never run
- concurrently with each other.
- The executor type `net::strand` meets these requirements. Use of a
- strand as the executor in the stream class template offers an additional
- notational convenience: the strand does not need to be specified in
- each individual initiating function call.
- Unlike other stream wrappers, the underlying socket is accessed
- through the @ref socket member function instead of `next_layer`.
- This causes the @ref basic_stream to be returned in calls
- to @ref get_lowest_layer.
- @par Usage
- To use this stream declare an instance of the class. Then, before
- each logical operation for which a timeout is desired, call
- @ref expires_after with a duration, or call @ref expires_at with a
- time point. Alternatively, call @ref expires_never to disable the
- timeout for subsequent logical operations. A logical operation
- is any series of one or more direct or indirect calls to the timeout
- stream's asynchronous read, asynchronous write, or asynchronous connect
- functions.
- When a timeout is set and a mixed operation is performed (one that
- includes both reads and writes, for example) the timeout applies
- to all of the intermediate asynchronous operations used in the
- enclosing operation. This allows timeouts to be applied to stream
- algorithms which were not written specifically to allow for timeouts,
- when those algorithms are passed a timeout stream with a timeout set.
- When a timeout occurs the socket will be closed, canceling any
- pending I/O operations. The completion handlers for these canceled
- operations will be invoked with the error @ref beast::error::timeout.
- @par Examples
- This function reads an HTTP request with a timeout, then sends the
- HTTP response with a different timeout.
- @code
- void process_http_1 (tcp_stream& stream, net::yield_context yield)
- {
- flat_buffer buffer;
- http::request<http::empty_body> req;
- // Read the request, with a 15 second timeout
- stream.expires_after(std::chrono::seconds(15));
- http::async_read(stream, buffer, req, yield);
- // Calculate the response
- http::response<http::string_body> res = make_response(req);
- // Send the response, with a 30 second timeout.
- stream.expires_after (std::chrono::seconds(30));
- http::async_write (stream, res, yield);
- }
- @endcode
- The example above could be expressed using a single timeout with a
- simple modification. The function that follows first reads an HTTP
- request then sends the HTTP response, with a single timeout that
- applies to the entire combined operation of reading and writing:
- @code
- void process_http_2 (tcp_stream& stream, net::yield_context yield)
- {
- flat_buffer buffer;
- http::request<http::empty_body> req;
- // Require that the read and write combined take no longer than 30 seconds
- stream.expires_after(std::chrono::seconds(30));
- http::async_read(stream, buffer, req, yield);
- http::response<http::string_body> res = make_response(req);
- http::async_write (stream, res, yield);
- }
- @endcode
- Some stream algorithms, such as `ssl::stream::async_handshake` perform
- both reads and writes. A timeout set before calling the initiating function
- of such composite stream algorithms will apply to the entire composite
- operation. For example, a timeout may be set on performing the SSL handshake
- thusly:
- @code
- void do_ssl_handshake (net::ssl::stream<tcp_stream>& stream, net::yield_context yield)
- {
- // Require that the SSL handshake take no longer than 10 seconds
- stream.expires_after(std::chrono::seconds(10));
- stream.async_handshake(net::ssl::stream_base::client, yield);
- }
- @endcode
- @par Blocking I/O
- Synchronous functions behave identically as that of the wrapped
- `net::basic_stream_socket`. Timeouts are not available when performing
- blocking calls.
- @tparam Protocol A type meeting the requirements of <em>Protocol</em>
- representing the protocol the protocol to use for the basic stream socket.
- A common choice is `net::ip::tcp`.
- @tparam Executor A type meeting the requirements of <em>Executor</em> to
- be used for submitting all completion handlers which do not already have an
- associated executor. If this type is omitted, the default of `net::any_io_executor`
- will be used.
- @par Thread Safety
- <em>Distinct objects</em>: Safe.@n
- <em>Shared objects</em>: Unsafe. The application must also ensure
- that all asynchronous operations are performed within the same
- implicit or explicit strand.
- @see
- @li <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1322r0.html">[P1322R0] Networking TS enhancement to enable custom I/O executors</a>.
- */
- template<
- class Protocol,
- class Executor = net::any_io_executor,
- class RatePolicy = unlimited_rate_policy
- >
- class basic_stream
- #if ! BHO_BEAST_DOXYGEN
- : private detail::stream_base
- #endif
- {
- public:
- /// The type of the underlying socket.
- using socket_type =
- net::basic_stream_socket<Protocol, Executor>;
- /** The type of the executor associated with the stream.
- This will be the type of executor used to invoke completion
- handlers which do not have an explicit associated executor.
- */
- using executor_type = beast::executor_type<socket_type>;
- /// Rebinds the stream type to another executor.
- template<class Executor1>
- struct rebind_executor
- {
- /// The stream type when rebound to the specified executor.
- using other = basic_stream<
- Protocol, Executor1, RatePolicy>;
- };
- /// The protocol type.
- using protocol_type = Protocol;
- /// The endpoint type.
- using endpoint_type = typename Protocol::endpoint;
- private:
- using op_state = basic_op_state<Executor>;
- static_assert(
- net::is_executor<Executor>::value || net::execution::is_executor<Executor>::value,
- "Executor type requirements not met");
- struct impl_type
- : std::enable_shared_from_this<impl_type>
- , bho::empty_value<RatePolicy>
- {
- // must come first
- net::basic_stream_socket<
- Protocol, Executor> socket;
- op_state read;
- op_state write;
- net::basic_waitable_timer<
- std::chrono::steady_clock,
- net::wait_traits<
- std::chrono::steady_clock>,
- Executor> timer; // rate timer;
- int waiting = 0;
- impl_type(impl_type&&) = default;
- template<class... Args>
- explicit
- impl_type(std::false_type, Args&&...);
- template<class RatePolicy_, class... Args>
- explicit
- impl_type(std::true_type,
- RatePolicy_&& policy, Args&&...);
- impl_type& operator=(impl_type&&) = delete;
- beast::executor_type<socket_type>
- ex() noexcept
- {
- return this->socket.get_executor();
- }
- RatePolicy&
- policy() noexcept
- {
- return this->bho::empty_value<RatePolicy>::get();
- }
- RatePolicy const&
- policy() const noexcept
- {
- return this->bho::empty_value<RatePolicy>::get();
- }
- template<class Executor2>
- void on_timer(Executor2 const& ex2);
- void reset(); // set timeouts to never
- void close() noexcept; // cancel everything
- };
- // We use shared ownership for the state so it can
- // outlive the destruction of the stream_socket object,
- // in the case where there is no outstanding read or write
- // but the implementation is still waiting on a timer.
- std::shared_ptr<impl_type> impl_;
- template<class Executor2>
- struct timeout_handler;
- struct ops;
- #if ! BHO_BEAST_DOXYGEN
- // asio::ssl::stream needs these
- // DEPRECATED
- template<class>
- friend class asio::ssl::stream;
- // DEPRECATED
- using lowest_layer_type = socket_type;
- // DEPRECATED
- lowest_layer_type&
- lowest_layer() noexcept
- {
- return impl_->socket;
- }
- // DEPRECATED
- lowest_layer_type const&
- lowest_layer() const noexcept
- {
- return impl_->socket;
- }
- #endif
- public:
- /** Destructor
- This function destroys the stream, cancelling any outstanding
- asynchronous operations associated with the socket as if by
- calling cancel.
- */
- ~basic_stream();
- /** Constructor
- This constructor creates the stream by forwarding all arguments
- to the underlying socket. The socket then needs to be open and
- connected or accepted before data can be sent or received on it.
- @param args A list of parameters forwarded to the constructor of
- the underlying socket.
- */
- #if BHO_BEAST_DOXYGEN
- template<class... Args>
- explicit
- basic_stream(Args&&... args);
- #else
- template<class Arg0, class... Args,
- class = typename std::enable_if<
- ! std::is_constructible<RatePolicy, Arg0>::value>::type>
- explicit
- basic_stream(Arg0&& argo, Args&&... args);
- /** Constructor
- *
- * A constructor that rebinds the executor.
- *
- * @tparam Executor_ The new executor
- * @param other The original socket to be rebound.
- */
- template<class Executor_>
- explicit
- basic_stream(basic_stream<Protocol, Executor_, RatePolicy> && other);
- template<typename, typename, typename>
- friend class basic_stream;
- #endif
- /** Constructor
- This constructor creates the stream with the specified rate
- policy, and forwards all remaining arguments to the underlying
- socket. The socket then needs to be open and connected or
- accepted before data can be sent or received on it.
- @param policy The rate policy object to use. The stream will
- take ownership of this object by decay-copy.
- @param args A list of parameters forwarded to the constructor of
- the underlying socket.
- */
- #if BHO_BEAST_DOXYGEN
- template<class RatePolicy_, class... Args>
- explicit
- basic_stream(RatePolicy_&& policy, Args&&... args);
- #else
- template<class RatePolicy_, class Arg0, class... Args,
- class = typename std::enable_if<
- std::is_constructible<
- RatePolicy, RatePolicy_>::value>::type>
- basic_stream(
- RatePolicy_&& policy, Arg0&& arg, Args&&... args);
- #endif
- /** Move constructor
- @param other The other object from which the move will occur.
- @note Following the move, the moved-from object is in the
- same state as if newly constructed.
- */
- basic_stream(basic_stream&& other);
- /// Move assignment (deleted).
- basic_stream& operator=(basic_stream&&) = delete;
- /// Return a reference to the underlying socket
- socket_type&
- socket() noexcept
- {
- return impl_->socket;
- }
- /// Return a reference to the underlying socket
- socket_type const&
- socket() const noexcept
- {
- return impl_->socket;
- }
- /** Release ownership of the underlying socket.
- This function causes all outstanding asynchronous connect,
- read, and write operations to be canceled as if by a call
- to @ref cancel. Ownership of the underlying socket is then
- transferred to the caller.
- */
- socket_type
- release_socket();
- //--------------------------------------------------------------------------
- /// Returns the rate policy associated with the object
- RatePolicy&
- rate_policy() noexcept
- {
- return impl_->policy();
- }
- /// Returns the rate policy associated with the object
- RatePolicy const&
- rate_policy() const noexcept
- {
- return impl_->policy();
- }
- /** Set the timeout for the next logical operation.
- This sets either the read timer, the write timer, or
- both timers to expire after the specified amount of time
- has elapsed. If a timer expires when the corresponding
- asynchronous operation is outstanding, the stream will be
- closed and any outstanding operations will complete with the
- error @ref beast::error::timeout. Otherwise, if the timer
- expires while no operations are outstanding, and the expiraton
- is not set again, the next operation will time out immediately.
- The timer applies collectively to any asynchronous reads
- or writes initiated after the expiration is set, until the
- expiration is set again. A call to @ref async_connect
- counts as both a read and a write.
- @param expiry_time The amount of time after which a logical
- operation should be considered timed out.
- */
- void
- expires_after(
- net::steady_timer::duration expiry_time);
- /** Set the timeout for the next logical operation.
- This sets either the read timer, the write timer, or both
- timers to expire at the specified time point. If a timer
- expires when the corresponding asynchronous operation is
- outstanding, the stream will be closed and any outstanding
- operations will complete with the error @ref beast::error::timeout.
- Otherwise, if the timer expires while no operations are outstanding,
- and the expiraton is not set again, the next operation will time out
- immediately.
- The timer applies collectively to any asynchronous reads
- or writes initiated after the expiration is set, until the
- expiration is set again. A call to @ref async_connect
- counts as both a read and a write.
- @param expiry_time The time point after which a logical
- operation should be considered timed out.
- */
- void
- expires_at(net::steady_timer::time_point expiry_time);
- /// Disable the timeout for the next logical operation.
- void
- expires_never();
- /** Cancel all asynchronous operations associated with the socket.
- This function causes all outstanding asynchronous connect,
- read, and write operations to finish immediately. Completion
- handlers for cancelled operations will receive the error
- `net::error::operation_aborted`. Completion handlers not
- yet invoked whose operations have completed, will receive
- the error corresponding to the result of the operation (which
- may indicate success).
- */
- void
- cancel();
- /** Close the timed stream.
- This cancels all of the outstanding asynchronous operations
- as if by calling @ref cancel, and closes the underlying socket.
- */
- void
- close();
- //--------------------------------------------------------------------------
- /** Get the executor associated with the object.
- This function may be used to obtain the executor object that the
- stream uses to dispatch completion handlers without an assocaited
- executor.
- @return A copy of the executor that stream will use to dispatch handlers.
- */
- executor_type
- get_executor() noexcept
- {
- return impl_->ex();
- }
- /** Connect the stream to the specified endpoint.
- This function is used to connect the underlying socket to the
- specified remote endpoint. The function call will block until
- the connection is successfully made or an error occurs.
- The underlying socket is automatically opened if needed.
- An automatically opened socket is not returned to the
- closed state upon failure.
- @param ep The remote endpoint to connect to.
- @throws system_error Thrown on failure.
- @see connect
- */
- void
- connect(endpoint_type const& ep)
- {
- socket().connect(ep);
- }
- /** Connect the stream to the specified endpoint.
- This function is used to connect the underlying socket to the
- specified remote endpoint. The function call will block until
- the connection is successfully made or an error occurs.
- The underlying socket is automatically opened if needed.
- An automatically opened socket is not returned to the
- closed state upon failure.
- @param ep The remote endpoint to connect to.
- @param ec Set to indicate what error occurred, if any.
- @see connect
- */
- void
- connect(endpoint_type const& ep, error_code& ec)
- {
- socket().connect(ep, ec);
- }
- /** Establishes a connection by trying each endpoint in a sequence.
- This function attempts to connect the stream to one of a sequence of
- endpoints by trying each endpoint until a connection is successfully
- established.
- The underlying socket is automatically opened if needed.
- An automatically opened socket is not returned to the
- closed state upon failure.
- The algorithm, known as a <em>composed operation</em>, is implemented
- in terms of calls to the underlying socket's `connect` function.
- @param endpoints A sequence of endpoints.
- @returns The successfully connected endpoint.
- @throws system_error Thrown on failure. If the sequence is
- empty, the associated error code is `net::error::not_found`.
- Otherwise, contains the error from the last connection attempt.
- */
- template<class EndpointSequence
- #if ! BHO_BEAST_DOXYGEN
- ,class = typename std::enable_if<
- net::is_endpoint_sequence<
- EndpointSequence>::value>::type
- #endif
- >
- typename Protocol::endpoint
- connect(EndpointSequence const& endpoints)
- {
- return net::connect(socket(), endpoints);
- }
- /** Establishes a connection by trying each endpoint in a sequence.
- This function attempts to connect the stream to one of a sequence of
- endpoints by trying each endpoint until a connection is successfully
- established.
- The underlying socket is automatically opened if needed.
- An automatically opened socket is not returned to the
- closed state upon failure.
- The algorithm, known as a <em>composed operation</em>, is implemented
- in terms of calls to the underlying socket's `connect` function.
- @param endpoints A sequence of endpoints.
- @param ec Set to indicate what error occurred, if any. If the sequence is
- empty, set to `net::error::not_found`. Otherwise, contains the error
- from the last connection attempt.
- @returns On success, the successfully connected endpoint. Otherwise, a
- default-constructed endpoint.
- */
- template<class EndpointSequence
- #if ! BHO_BEAST_DOXYGEN
- ,class = typename std::enable_if<
- net::is_endpoint_sequence<
- EndpointSequence>::value>::type
- #endif
- >
- typename Protocol::endpoint
- connect(
- EndpointSequence const& endpoints,
- error_code& ec
- )
- {
- return net::connect(socket(), endpoints, ec);
- }
- /** Establishes a connection by trying each endpoint in a sequence.
- This function attempts to connect the stream to one of a sequence of
- endpoints by trying each endpoint until a connection is successfully
- established.
- The underlying socket is automatically opened if needed.
- An automatically opened socket is not returned to the
- closed state upon failure.
- The algorithm, known as a <em>composed operation</em>, is implemented
- in terms of calls to the underlying socket's `connect` function.
- @param begin An iterator pointing to the start of a sequence of endpoints.
- @param end An iterator pointing to the end of a sequence of endpoints.
- @returns An iterator denoting the successfully connected endpoint.
- @throws system_error Thrown on failure. If the sequence is
- empty, the associated error code is `net::error::not_found`.
- Otherwise, contains the error from the last connection attempt.
- */
- template<class Iterator>
- Iterator
- connect(
- Iterator begin, Iterator end)
- {
- return net::connect(socket(), begin, end);
- }
- /** Establishes a connection by trying each endpoint in a sequence.
- This function attempts to connect the stream to one of a sequence of
- endpoints by trying each endpoint until a connection is successfully
- established.
- The underlying socket is automatically opened if needed.
- An automatically opened socket is not returned to the
- closed state upon failure.
- The algorithm, known as a <em>composed operation</em>, is implemented
- in terms of calls to the underlying socket's `connect` function.
- @param begin An iterator pointing to the start of a sequence of endpoints.
- @param end An iterator pointing to the end of a sequence of endpoints.
- @param ec Set to indicate what error occurred, if any. If the sequence is
- empty, set to asio::error::not_found. Otherwise, contains the error
- from the last connection attempt.
- @returns On success, an iterator denoting the successfully connected
- endpoint. Otherwise, the end iterator.
- */
- template<class Iterator>
- Iterator
- connect(
- Iterator begin, Iterator end,
- error_code& ec)
- {
- return net::connect(socket(), begin, end, ec);
- }
- /** Establishes a connection by trying each endpoint in a sequence.
- This function attempts to connect the stream to one of a sequence of
- endpoints by trying each endpoint until a connection is successfully
- established.
- The underlying socket is automatically opened if needed.
- An automatically opened socket is not returned to the
- closed state upon failure.
- The algorithm, known as a <em>composed operation</em>, is implemented
- in terms of calls to the underlying socket's `connect` function.
- @param endpoints A sequence of endpoints.
- @param connect_condition A function object that is called prior to each
- connection attempt. The signature of the function object must be:
- @code
- bool connect_condition(
- error_code const& ec,
- typename Protocol::endpoint const& next);
- @endcode
- The @c ec parameter contains the result from the most recent connect
- operation. Before the first connection attempt, @c ec is always set to
- indicate success. The @c next parameter is the next endpoint to be tried.
- The function object should return true if the next endpoint should be tried,
- and false if it should be skipped.
- @returns The successfully connected endpoint.
- @throws asio::system_error Thrown on failure. If the sequence is
- empty, the associated error code is `net::error::not_found`.
- Otherwise, contains the error from the last connection attempt.
- */
- template<
- class EndpointSequence, class ConnectCondition
- #if ! BHO_BEAST_DOXYGEN
- ,class = typename std::enable_if<
- net::is_endpoint_sequence<
- EndpointSequence>::value>::type
- #endif
- >
- typename Protocol::endpoint
- connect(
- EndpointSequence const& endpoints,
- ConnectCondition connect_condition
- )
- {
- return net::connect(socket(), endpoints, connect_condition);
- }
- /** Establishes a connection by trying each endpoint in a sequence.
- This function attempts to connect the stream to one of a sequence of
- endpoints by trying each endpoint until a connection is successfully
- established.
- The underlying socket is automatically opened if needed.
- An automatically opened socket is not returned to the
- closed state upon failure.
- The algorithm, known as a <em>composed operation</em>, is implemented
- in terms of calls to the underlying socket's `connect` function.
- @param endpoints A sequence of endpoints.
- @param connect_condition A function object that is called prior to each
- connection attempt. The signature of the function object must be:
- @code
- bool connect_condition(
- error_code const& ec,
- typename Protocol::endpoint const& next);
- @endcode
- The @c ec parameter contains the result from the most recent connect
- operation. Before the first connection attempt, @c ec is always set to
- indicate success. The @c next parameter is the next endpoint to be tried.
- The function object should return true if the next endpoint should be tried,
- and false if it should be skipped.
- @param ec Set to indicate what error occurred, if any. If the sequence is
- empty, set to `net::error::not_found`. Otherwise, contains the error
- from the last connection attempt.
- @returns On success, the successfully connected endpoint. Otherwise, a
- default-constructed endpoint.
- */
- template<
- class EndpointSequence, class ConnectCondition
- #if ! BHO_BEAST_DOXYGEN
- ,class = typename std::enable_if<
- net::is_endpoint_sequence<
- EndpointSequence>::value>::type
- #endif
- >
- typename Protocol::endpoint
- connect(
- EndpointSequence const& endpoints,
- ConnectCondition connect_condition,
- error_code& ec)
- {
- return net::connect(socket(), endpoints, connect_condition, ec);
- }
- /** Establishes a connection by trying each endpoint in a sequence.
- This function attempts to connect the stream to one of a sequence of
- endpoints by trying each endpoint until a connection is successfully
- established.
- The underlying socket is automatically opened if needed.
- An automatically opened socket is not returned to the
- closed state upon failure.
- The algorithm, known as a <em>composed operation</em>, is implemented
- in terms of calls to the underlying socket's `connect` function.
- @param begin An iterator pointing to the start of a sequence of endpoints.
- @param end An iterator pointing to the end of a sequence of endpoints.
- @param connect_condition A function object that is called prior to each
- connection attempt. The signature of the function object must be:
- @code
- bool connect_condition(
- error_code const& ec,
- typename Protocol::endpoint const& next);
- @endcode
- The @c ec parameter contains the result from the most recent connect
- operation. Before the first connection attempt, @c ec is always set to
- indicate success. The @c next parameter is the next endpoint to be tried.
- The function object should return true if the next endpoint should be tried,
- and false if it should be skipped.
- @returns An iterator denoting the successfully connected endpoint.
- @throws asio::system_error Thrown on failure. If the sequence is
- empty, the associated @c error_code is `net::error::not_found`.
- Otherwise, contains the error from the last connection attempt.
- */
- template<
- class Iterator, class ConnectCondition>
- Iterator
- connect(
- Iterator begin, Iterator end,
- ConnectCondition connect_condition)
- {
- return net::connect(socket(), begin, end, connect_condition);
- }
- /** Establishes a connection by trying each endpoint in a sequence.
- This function attempts to connect the stream to one of a sequence of
- endpoints by trying each endpoint until a connection is successfully
- established.
- The underlying socket is automatically opened if needed.
- An automatically opened socket is not returned to the
- closed state upon failure.
- The algorithm, known as a <em>composed operation</em>, is implemented
- in terms of calls to the underlying socket's `connect` function.
- @param begin An iterator pointing to the start of a sequence of endpoints.
- @param end An iterator pointing to the end of a sequence of endpoints.
- @param connect_condition A function object that is called prior to each
- connection attempt. The signature of the function object must be:
- @code
- bool connect_condition(
- error_code const& ec,
- typename Protocol::endpoint const& next);
- @endcode
- The @c ec parameter contains the result from the most recent connect
- operation. Before the first connection attempt, @c ec is always set to
- indicate success. The @c next parameter is the next endpoint to be tried.
- The function object should return true if the next endpoint should be tried,
- and false if it should be skipped.
- @param ec Set to indicate what error occurred, if any. If the sequence is
- empty, set to `net::error::not_found`. Otherwise, contains the error
- from the last connection attempt.
- @returns On success, an iterator denoting the successfully connected
- endpoint. Otherwise, the end iterator.
- */
- template<
- class Iterator, class ConnectCondition>
- Iterator
- connect(
- Iterator begin, Iterator end,
- ConnectCondition connect_condition,
- error_code& ec)
- {
- return net::connect(socket(), begin, end, connect_condition, ec);
- }
- /** Connect the stream to the specified endpoint asynchronously.
- This function is used to asynchronously connect the underlying
- socket to the specified remote endpoint. The function call always
- returns immediately.
- The underlying socket is automatically opened if needed.
- An automatically opened socket is not returned to the
- closed state upon failure.
- If the timeout timer expires while the operation is outstanding,
- the operation will be canceled and the completion handler will be
- invoked with the error @ref error::timeout.
- @param ep The remote endpoint to which the underlying socket will be
- connected. Copies will be made of the endpoint object as required.
- @param handler The completion handler to invoke when the operation
- completes. The implementation takes ownership of the handler by
- performing a decay-copy. The equivalent function signature of
- the handler must be:
- @code
- void handler(
- error_code ec // Result of operation
- );
- @endcode
- If the handler has an associated immediate executor,
- an immediate completion will be dispatched to it.
- Otherwise, the handler will not be invoked from within
- this function. Invocation of the handler will be performed
- by dispatching to the immediate executor. If no
- immediate executor is specified, this is equivalent
- to using `net::post`.
- @par Per-Operation Cancellation
- This asynchronous operation supports cancellation for the following
- net::cancellation_type values:
- @li @c net::cancellation_type::terminal
- @li @c net::cancellation_type::partial
- @li @c net::cancellation_type::total
- if they are also supported by the socket's @c async_connect operation.
- @see async_connect
- */
- template<
- BHO_BEAST_ASYNC_TPARAM1 ConnectHandler =
- net::default_completion_token_t<executor_type>
- >
- BHO_BEAST_ASYNC_RESULT1(ConnectHandler)
- async_connect(
- endpoint_type const& ep,
- ConnectHandler&& handler =
- net::default_completion_token_t<
- executor_type>{});
- /** Establishes a connection by trying each endpoint in a sequence asynchronously.
- This function attempts to connect the stream to one of a sequence of
- endpoints by trying each endpoint until a connection is successfully
- established.
- The underlying socket is automatically opened if needed.
- An automatically opened socket is not returned to the
- closed state upon failure.
- The algorithm, known as a <em>composed asynchronous operation</em>, is
- implemented in terms of calls to the underlying socket's `async_connect`
- function.
- If the timeout timer expires while the operation is outstanding,
- the current connection attempt will be canceled and the completion
- handler will be invoked with the error @ref error::timeout.
- @param endpoints A sequence of endpoints. This this object must meet
- the requirements of <em>EndpointSequence</em>.
- @param handler The completion handler to invoke when the operation
- completes. The implementation takes ownership of the handler by
- performing a decay-copy. The equivalent function signature of
- the handler must be:
- @code
- void handler(
- // Result of operation. if the sequence is empty, set to
- // net::error::not_found. Otherwise, contains the
- // error from the last connection attempt.
- error_code const& error,
- // On success, the successfully connected endpoint.
- // Otherwise, a default-constructed endpoint.
- typename Protocol::endpoint const& endpoint
- );
- @endcode
- If the handler has an associated immediate executor,
- an immediate completion will be dispatched to it.
- Otherwise, the handler will not be invoked from within
- this function. Invocation of the handler will be performed
- by dispatching to the immediate executor. If no
- immediate executor is specified, this is equivalent
- to using `net::post`.
- @par Per-Operation Cancellation
- This asynchronous operation supports cancellation for the following
- net::cancellation_type values:
- @li @c net::cancellation_type::terminal
- @li @c net::cancellation_type::partial
- @li @c net::cancellation_type::total
- if they are also supported by the socket's @c async_connect operation.
- */
- template<
- class EndpointSequence,
- ASIO_COMPLETION_TOKEN_FOR(
- void(error_code, typename Protocol::endpoint))
- RangeConnectHandler =
- net::default_completion_token_t<executor_type>
- #if ! BHO_BEAST_DOXYGEN
- ,class = typename std::enable_if<
- net::is_endpoint_sequence<
- EndpointSequence>::value>::type
- #endif
- >
- ASIO_INITFN_AUTO_RESULT_TYPE(
- RangeConnectHandler,
- void(error_code, typename Protocol::endpoint))
- async_connect(
- EndpointSequence const& endpoints,
- RangeConnectHandler&& handler =
- net::default_completion_token_t<executor_type>{});
- /** Establishes a connection by trying each endpoint in a sequence asynchronously.
- This function attempts to connect the stream to one of a sequence of
- endpoints by trying each endpoint until a connection is successfully
- established.
- The underlying socket is automatically opened if needed.
- An automatically opened socket is not returned to the
- closed state upon failure.
- The algorithm, known as a <em>composed asynchronous operation</em>, is
- implemented in terms of calls to the underlying socket's `async_connect`
- function.
- If the timeout timer expires while the operation is outstanding,
- the current connection attempt will be canceled and the completion
- handler will be invoked with the error @ref error::timeout.
- @param endpoints A sequence of endpoints. This this object must meet
- the requirements of <em>EndpointSequence</em>.
- @param connect_condition A function object that is called prior to each
- connection attempt. The signature of the function object must be:
- @code
- bool connect_condition(
- error_code const& ec,
- typename Protocol::endpoint const& next);
- @endcode
- The @c ec parameter contains the result from the most recent connect
- operation. Before the first connection attempt, @c ec is always set to
- indicate success. The @c next parameter is the next endpoint to be tried.
- The function object should return true if the next endpoint should be tried,
- and false if it should be skipped.
- @param handler The completion handler to invoke when the operation
- completes. The implementation takes ownership of the handler by
- performing a decay-copy. The equivalent function signature of
- the handler must be:
- @code
- void handler(
- // Result of operation. if the sequence is empty, set to
- // net::error::not_found. Otherwise, contains the
- // error from the last connection attempt.
- error_code const& error,
- // On success, the successfully connected endpoint.
- // Otherwise, a default-constructed endpoint.
- typename Protocol::endpoint const& endpoint
- );
- @endcode
- If the handler has an associated immediate executor,
- an immediate completion will be dispatched to it.
- Otherwise, the handler will not be invoked from within
- this function. Invocation of the handler will be performed
- by dispatching to the immediate executor. If no
- immediate executor is specified, this is equivalent
- to using `net::post`.
- @par Example
- The following connect condition function object can be used to output
- information about the individual connection attempts:
- @code
- struct my_connect_condition
- {
- bool operator()(
- error_code const& ec,
- net::ip::tcp::endpoint const& next)
- {
- if (ec)
- std::cout << "Error: " << ec.message() << std::endl;
- std::cout << "Trying: " << next << std::endl;
- return true;
- }
- };
- @endcode
- @par Per-Operation Cancellation
- This asynchronous operation supports cancellation for the following
- net::cancellation_type values:
- @li @c net::cancellation_type::terminal
- @li @c net::cancellation_type::partial
- @li @c net::cancellation_type::total
- if they are also supported by the socket's @c async_connect operation.
- */
- template<
- class EndpointSequence,
- class ConnectCondition,
- ASIO_COMPLETION_TOKEN_FOR(
- void(error_code, typename Protocol::endpoint))
- RangeConnectHandler =
- net::default_completion_token_t<executor_type>
- #if ! BHO_BEAST_DOXYGEN
- ,class = typename std::enable_if<
- net::is_endpoint_sequence<
- EndpointSequence>::value>::type
- #endif
- >
- ASIO_INITFN_AUTO_RESULT_TYPE(
- RangeConnectHandler,
- void(error_code, typename Protocol::endpoint))
- async_connect(
- EndpointSequence const& endpoints,
- ConnectCondition connect_condition,
- RangeConnectHandler&& handler =
- net::default_completion_token_t<
- executor_type>{});
- /** Establishes a connection by trying each endpoint in a sequence asynchronously.
- This function attempts to connect the stream to one of a sequence of
- endpoints by trying each endpoint until a connection is successfully
- established.
- The underlying socket is automatically opened if needed.
- An automatically opened socket is not returned to the
- closed state upon failure.
- The algorithm, known as a <em>composed asynchronous operation</em>, is
- implemented in terms of calls to the underlying socket's `async_connect`
- function.
- If the timeout timer expires while the operation is outstanding,
- the current connection attempt will be canceled and the completion
- handler will be invoked with the error @ref error::timeout.
- @param begin An iterator pointing to the start of a sequence of endpoints.
- @param end An iterator pointing to the end of a sequence of endpoints.
- @param handler The completion handler to invoke when the operation
- completes. The implementation takes ownership of the handler by
- performing a decay-copy. The equivalent function signature of
- the handler must be:
- @code
- void handler(
- // Result of operation. if the sequence is empty, set to
- // net::error::not_found. Otherwise, contains the
- // error from the last connection attempt.
- error_code const& error,
- // On success, an iterator denoting the successfully
- // connected endpoint. Otherwise, the end iterator.
- Iterator iterator
- );
- @endcode
- If the handler has an associated immediate executor,
- an immediate completion will be dispatched to it.
- Otherwise, the handler will not be invoked from within
- this function. Invocation of the handler will be performed
- by dispatching to the immediate executor. If no
- immediate executor is specified, this is equivalent
- to using `net::post`.
- @par Per-Operation Cancellation
- This asynchronous operation supports cancellation for the following
- net::cancellation_type values:
- @li @c net::cancellation_type::terminal
- @li @c net::cancellation_type::partial
- @li @c net::cancellation_type::total
- if they are also supported by the socket's @c async_connect operation.
- */
- template<
- class Iterator,
- ASIO_COMPLETION_TOKEN_FOR(
- void(error_code, Iterator))
- IteratorConnectHandler =
- net::default_completion_token_t<executor_type>>
- ASIO_INITFN_AUTO_RESULT_TYPE(
- IteratorConnectHandler,
- void(error_code, Iterator))
- async_connect(
- Iterator begin, Iterator end,
- IteratorConnectHandler&& handler =
- net::default_completion_token_t<executor_type>{});
- /** Establishes a connection by trying each endpoint in a sequence asynchronously.
- This function attempts to connect the stream to one of a sequence of
- endpoints by trying each endpoint until a connection is successfully
- established.
- The algorithm, known as a <em>composed asynchronous operation</em>, is
- implemented in terms of calls to the underlying socket's `async_connect`
- function.
- If the timeout timer expires while the operation is outstanding,
- the current connection attempt will be canceled and the completion
- handler will be invoked with the error @ref error::timeout.
- @param begin An iterator pointing to the start of a sequence of endpoints.
- @param end An iterator pointing to the end of a sequence of endpoints.
- @param connect_condition A function object that is called prior to each
- connection attempt. The signature of the function object must be:
- @code
- bool connect_condition(
- error_code const& ec,
- typename Protocol::endpoint const& next);
- @endcode
- @param handler The completion handler to invoke when the operation
- completes. The implementation takes ownership of the handler by
- performing a decay-copy. The equivalent function signature of
- the handler must be:
- @code
- void handler(
- // Result of operation. if the sequence is empty, set to
- // net::error::not_found. Otherwise, contains the
- // error from the last connection attempt.
- error_code const& error,
- // On success, an iterator denoting the successfully
- // connected endpoint. Otherwise, the end iterator.
- Iterator iterator
- );
- @endcode
- If the handler has an associated immediate executor,
- an immediate completion will be dispatched to it.
- Otherwise, the handler will not be invoked from within
- this function. Invocation of the handler will be performed
- by dispatching to the immediate executor. If no
- immediate executor is specified, this is equivalent
- to using `net::post`.
- @par Per-Operation Cancellation
- This asynchronous operation supports cancellation for the following
- net::cancellation_type values:
- @li @c net::cancellation_type::terminal
- @li @c net::cancellation_type::partial
- @li @c net::cancellation_type::total
- if they are also supported by the socket's @c async_connect operation.
- */
- template<
- class Iterator,
- class ConnectCondition,
- ASIO_COMPLETION_TOKEN_FOR(
- void(error_code, Iterator))
- IteratorConnectHandler =
- net::default_completion_token_t<executor_type>>
- ASIO_INITFN_AUTO_RESULT_TYPE(
- IteratorConnectHandler,
- void(error_code, Iterator))
- async_connect(
- Iterator begin, Iterator end,
- ConnectCondition connect_condition,
- IteratorConnectHandler&& handler =
- net::default_completion_token_t<executor_type>{});
- //--------------------------------------------------------------------------
- /** Read some data.
- This function is used to read some data from the stream.
- The call blocks until one of the following is true:
- @li One or more bytes are read from the stream.
- @li An error occurs.
- @param buffers The buffers into which the data will be read. If the
- size of the buffers is zero bytes, the call always returns
- immediately with no error.
- @returns The number of bytes read.
- @throws system_error Thrown on failure.
- @note The `read_some` operation may not receive all of the requested
- number of bytes. Consider using the function `net::read` if you need
- to ensure that the requested amount of data is read before the
- blocking operation completes.
- */
- template<class MutableBufferSequence>
- std::size_t
- read_some(MutableBufferSequence const& buffers)
- {
- return impl_->socket.read_some(buffers);
- }
- /** Read some data.
- This function is used to read some data from the underlying socket.
- The call blocks until one of the following is true:
- @li One or more bytes are read from the stream.
- @li An error occurs.
- @param buffers The buffers into which the data will be read. If the
- size of the buffers is zero bytes, the call always returns
- immediately with no error.
- @param ec Set to indicate what error occurred, if any.
- @returns The number of bytes read.
- @note The `read_some` operation may not receive all of the requested
- number of bytes. Consider using the function `net::read` if you need
- to ensure that the requested amount of data is read before the
- blocking operation completes.
- */
- template<class MutableBufferSequence>
- std::size_t
- read_some(
- MutableBufferSequence const& buffers,
- error_code& ec)
- {
- return impl_->socket.read_some(buffers, ec);
- }
- /** Read some data asynchronously.
- This function is used to asynchronously read data from the stream.
- This call always returns immediately. The asynchronous operation
- will continue until one of the following conditions is true:
- @li One or more bytes are read from the stream.
- @li An error occurs.
- The algorithm, known as a <em>composed asynchronous operation</em>,
- is implemented in terms of calls to the next layer's `async_read_some`
- function. The program must ensure that no other calls to @ref read_some
- or @ref async_read_some are performed until this operation completes.
- If the timeout timer expires while the operation is outstanding,
- the operation will be canceled and the completion handler will be
- invoked with the error @ref error::timeout.
- @param buffers The buffers into which the data will be read. If the size
- of the buffers is zero bytes, the operation always completes immediately
- with no error.
- Although the buffers object may be copied as necessary, ownership of the
- underlying memory blocks is retained by the caller, which must guarantee
- that they remain valid until the handler is called.
- @param handler The completion handler to invoke when the operation
- completes. The implementation takes ownership of the handler by
- performing a decay-copy. The equivalent function signature of
- the handler must be:
- @code
- void handler(
- error_code error, // Result of operation.
- std::size_t bytes_transferred // Number of bytes read.
- );
- @endcode
- If the handler has an associated immediate executor,
- an immediate completion will be dispatched to it.
- Otherwise, the handler will not be invoked from within
- this function. Invocation of the handler will be performed
- by dispatching to the immediate executor. If no
- immediate executor is specified, this is equivalent
- to using `net::post`.
- @note The `async_read_some` operation may not receive all of the requested
- number of bytes. Consider using the function `net::async_read` if you need
- to ensure that the requested amount of data is read before the asynchronous
- operation completes.
- @par Per-Operation Cancellation
- This asynchronous operation supports cancellation for the following
- net::cancellation_type values:
- @li @c net::cancellation_type::terminal
- @li @c net::cancellation_type::partial
- @li @c net::cancellation_type::total
- if they are also supported by the socket's @c async_read_some operation.
- */
- template<
- class MutableBufferSequence,
- BHO_BEAST_ASYNC_TPARAM2 ReadHandler =
- net::default_completion_token_t<executor_type>
- >
- BHO_BEAST_ASYNC_RESULT2(ReadHandler)
- async_read_some(
- MutableBufferSequence const& buffers,
- ReadHandler&& handler =
- net::default_completion_token_t<executor_type>{}
- );
- /** Write some data.
- This function is used to write some data to the stream.
- The call blocks until one of the following is true:
- @li One or more bytes are written to the stream.
- @li An error occurs.
- @param buffers The buffers from which the data will be written. If the
- size of the buffers is zero bytes, the call always returns immediately
- with no error.
- @returns The number of bytes written.
- @throws system_error Thrown on failure.
- @note The `write_some` operation may not transmit all of the requested
- number of bytes. Consider using the function `net::write` if you need
- to ensure that the requested amount of data is written before the
- blocking operation completes.
- */
- template<class ConstBufferSequence>
- std::size_t
- write_some(ConstBufferSequence const& buffers)
- {
- return impl_->socket.write_some(buffers);
- }
- /** Write some data.
- This function is used to write some data to the stream.
- The call blocks until one of the following is true:
- @li One or more bytes are written to the stream.
- @li An error occurs.
- @param buffers The buffers from which the data will be written. If the
- size of the buffers is zero bytes, the call always returns immediately
- with no error.
- @param ec Set to indicate what error occurred, if any.
- @returns The number of bytes written.
- @throws system_error Thrown on failure.
- @note The `write_some` operation may not transmit all of the requested
- number of bytes. Consider using the function `net::write` if you need
- to ensure that the requested amount of data is written before the
- blocking operation completes.
- */
- template<class ConstBufferSequence>
- std::size_t
- write_some(
- ConstBufferSequence const& buffers,
- error_code& ec)
- {
- return impl_->socket.write_some(buffers, ec);
- }
- /** Write some data asynchronously.
- This function is used to asynchronously write data to the underlying socket.
- This call always returns immediately. The asynchronous operation
- will continue until one of the following conditions is true:
- @li One or more bytes are written to the stream.
- @li An error occurs.
- The algorithm, known as a <em>composed asynchronous operation</em>,
- is implemented in terms of calls to the next layer's `async_write_some`
- function. The program must ensure that no other calls to @ref async_write_some
- are performed until this operation completes.
- If the timeout timer expires while the operation is outstanding,
- the operation will be canceled and the completion handler will be
- invoked with the error @ref error::timeout.
- @param buffers The buffers from which the data will be written. If the
- size of the buffers is zero bytes, the operation always completes
- immediately with no error.
- Although the buffers object may be copied as necessary, ownership of the
- underlying memory blocks is retained by the caller, which must guarantee
- that they remain valid until the handler is called.
- @param handler The completion handler to invoke when the operation
- completes. The implementation takes ownership of the handler by
- performing a decay-copy. The equivalent function signature of
- the handler must be:
- @code
- void handler(
- error_code error, // Result of operation.
- std::size_t bytes_transferred // Number of bytes written.
- );
- @endcode
- If the handler has an associated immediate executor,
- an immediate completion will be dispatched to it.
- Otherwise, the handler will not be invoked from within
- this function. Invocation of the handler will be performed
- by dispatching to the immediate executor. If no
- immediate executor is specified, this is equivalent
- to using `net::post`.
- @note The `async_write_some` operation may not transmit all of the requested
- number of bytes. Consider using the function `net::async_write` if you need
- to ensure that the requested amount of data is sent before the asynchronous
- operation completes.
- @par Per-Operation Cancellation
- This asynchronous operation supports cancellation for the following
- net::cancellation_type values:
- @li @c net::cancellation_type::terminal
- @li @c net::cancellation_type::partial
- @li @c net::cancellation_type::total
- if they are also supported by the socket's @c async_write_some operation.
- */
- template<
- class ConstBufferSequence,
- BHO_BEAST_ASYNC_TPARAM2 WriteHandler =
- net::default_completion_token_t<Executor>
- >
- BHO_BEAST_ASYNC_RESULT2(WriteHandler)
- async_write_some(
- ConstBufferSequence const& buffers,
- WriteHandler&& handler =
- net::default_completion_token_t<Executor>{});
- };
- } // beast
- } // bho
- #include <asio2/bho/beast/core/impl/basic_stream.hpp>
- #endif
|