1//
2// basic_stream_socket.hpp
3// ~~~~~~~~~~~~~~~~~~~~~~~
4//
5// Copyright (c) 2003-2024 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6//
7// Distributed under the Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9//
10
11#ifndef BOOST_ASIO_BASIC_STREAM_SOCKET_HPP
12#define BOOST_ASIO_BASIC_STREAM_SOCKET_HPP
13
14#if defined(_MSC_VER) && (_MSC_VER >= 1200)
15# pragma once
16#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17
18#include <boost/asio/detail/config.hpp>
19#include <cstddef>
20#include <boost/asio/async_result.hpp>
21#include <boost/asio/basic_socket.hpp>
22#include <boost/asio/detail/handler_type_requirements.hpp>
23#include <boost/asio/detail/non_const_lvalue.hpp>
24#include <boost/asio/detail/throw_error.hpp>
25#include <boost/asio/error.hpp>
26
27#include <boost/asio/detail/push_options.hpp>
28
29namespace boost {
30namespace asio {
31
32#if !defined(BOOST_ASIO_BASIC_STREAM_SOCKET_FWD_DECL)
33#define BOOST_ASIO_BASIC_STREAM_SOCKET_FWD_DECL
34
35// Forward declaration with defaulted arguments.
36template <typename Protocol, typename Executor = any_io_executor>
37class basic_stream_socket;
38
39#endif // !defined(BOOST_ASIO_BASIC_STREAM_SOCKET_FWD_DECL)
40
41/// Provides stream-oriented socket functionality.
42/**
43 * The basic_stream_socket class template provides asynchronous and blocking
44 * stream-oriented socket functionality.
45 *
46 * @par Thread Safety
47 * @e Distinct @e objects: Safe.@n
48 * @e Shared @e objects: Unsafe.
49 *
50 * Synchronous @c send, @c receive, @c connect, and @c shutdown operations are
51 * thread safe with respect to each other, if the underlying operating system
52 * calls are also thread safe. This means that it is permitted to perform
53 * concurrent calls to these synchronous operations on a single socket object.
54 * Other synchronous operations, such as @c open or @c close, are not thread
55 * safe.
56 *
57 * @par Concepts:
58 * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream.
59 */
60template <typename Protocol, typename Executor>
61class basic_stream_socket
62 : public basic_socket<Protocol, Executor>
63{
64private:
65 class initiate_async_send;
66 class initiate_async_receive;
67
68public:
69 /// The type of the executor associated with the object.
70 typedef Executor executor_type;
71
72 /// Rebinds the socket type to another executor.
73 template <typename Executor1>
74 struct rebind_executor
75 {
76 /// The socket type when rebound to the specified executor.
77 typedef basic_stream_socket<Protocol, Executor1> other;
78 };
79
80 /// The native representation of a socket.
81#if defined(GENERATING_DOCUMENTATION)
82 typedef implementation_defined native_handle_type;
83#else
84 typedef typename basic_socket<Protocol,
85 Executor>::native_handle_type native_handle_type;
86#endif
87
88 /// The protocol type.
89 typedef Protocol protocol_type;
90
91 /// The endpoint type.
92 typedef typename Protocol::endpoint endpoint_type;
93
94 /// Construct a basic_stream_socket without opening it.
95 /**
96 * This constructor creates a stream socket without opening it. The socket
97 * needs to be opened and then connected or accepted before data can be sent
98 * or received on it.
99 *
100 * @param ex The I/O executor that the socket will use, by default, to
101 * dispatch handlers for any asynchronous operations performed on the socket.
102 */
103 explicit basic_stream_socket(const executor_type& ex)
104 : basic_socket<Protocol, Executor>(ex)
105 {
106 }
107
108 /// Construct a basic_stream_socket without opening it.
109 /**
110 * This constructor creates a stream socket without opening it. The socket
111 * needs to be opened and then connected or accepted before data can be sent
112 * or received on it.
113 *
114 * @param context An execution context which provides the I/O executor that
115 * the socket will use, by default, to dispatch handlers for any asynchronous
116 * operations performed on the socket.
117 */
118 template <typename ExecutionContext>
119 explicit basic_stream_socket(ExecutionContext& context,
120 constraint_t<
121 is_convertible<ExecutionContext&, execution_context&>::value
122 > = 0)
123 : basic_socket<Protocol, Executor>(context)
124 {
125 }
126
127 /// Construct and open a basic_stream_socket.
128 /**
129 * This constructor creates and opens a stream socket. The socket needs to be
130 * connected or accepted before data can be sent or received on it.
131 *
132 * @param ex The I/O executor that the socket will use, by default, to
133 * dispatch handlers for any asynchronous operations performed on the socket.
134 *
135 * @param protocol An object specifying protocol parameters to be used.
136 *
137 * @throws boost::system::system_error Thrown on failure.
138 */
139 basic_stream_socket(const executor_type& ex, const protocol_type& protocol)
140 : basic_socket<Protocol, Executor>(ex, protocol)
141 {
142 }
143
144 /// Construct and open a basic_stream_socket.
145 /**
146 * This constructor creates and opens a stream socket. The socket needs to be
147 * connected or accepted before data can be sent or received on it.
148 *
149 * @param context An execution context which provides the I/O executor that
150 * the socket will use, by default, to dispatch handlers for any asynchronous
151 * operations performed on the socket.
152 *
153 * @param protocol An object specifying protocol parameters to be used.
154 *
155 * @throws boost::system::system_error Thrown on failure.
156 */
157 template <typename ExecutionContext>
158 basic_stream_socket(ExecutionContext& context, const protocol_type& protocol,
159 constraint_t<
160 is_convertible<ExecutionContext&, execution_context&>::value,
161 defaulted_constraint
162 > = defaulted_constraint())
163 : basic_socket<Protocol, Executor>(context, protocol)
164 {
165 }
166
167 /// Construct a basic_stream_socket, opening it and binding it to the given
168 /// local endpoint.
169 /**
170 * This constructor creates a stream socket and automatically opens it bound
171 * to the specified endpoint on the local machine. The protocol used is the
172 * protocol associated with the given endpoint.
173 *
174 * @param ex The I/O executor that the socket will use, by default, to
175 * dispatch handlers for any asynchronous operations performed on the socket.
176 *
177 * @param endpoint An endpoint on the local machine to which the stream
178 * socket will be bound.
179 *
180 * @throws boost::system::system_error Thrown on failure.
181 */
182 basic_stream_socket(const executor_type& ex, const endpoint_type& endpoint)
183 : basic_socket<Protocol, Executor>(ex, endpoint)
184 {
185 }
186
187 /// Construct a basic_stream_socket, opening it and binding it to the given
188 /// local endpoint.
189 /**
190 * This constructor creates a stream socket and automatically opens it bound
191 * to the specified endpoint on the local machine. The protocol used is the
192 * protocol associated with the given endpoint.
193 *
194 * @param context An execution context which provides the I/O executor that
195 * the socket will use, by default, to dispatch handlers for any asynchronous
196 * operations performed on the socket.
197 *
198 * @param endpoint An endpoint on the local machine to which the stream
199 * socket will be bound.
200 *
201 * @throws boost::system::system_error Thrown on failure.
202 */
203 template <typename ExecutionContext>
204 basic_stream_socket(ExecutionContext& context, const endpoint_type& endpoint,
205 constraint_t<
206 is_convertible<ExecutionContext&, execution_context&>::value
207 > = 0)
208 : basic_socket<Protocol, Executor>(context, endpoint)
209 {
210 }
211
212 /// Construct a basic_stream_socket on an existing native socket.
213 /**
214 * This constructor creates a stream socket object to hold an existing native
215 * socket.
216 *
217 * @param ex The I/O executor that the socket will use, by default, to
218 * dispatch handlers for any asynchronous operations performed on the socket.
219 *
220 * @param protocol An object specifying protocol parameters to be used.
221 *
222 * @param native_socket The new underlying socket implementation.
223 *
224 * @throws boost::system::system_error Thrown on failure.
225 */
226 basic_stream_socket(const executor_type& ex,
227 const protocol_type& protocol, const native_handle_type& native_socket)
228 : basic_socket<Protocol, Executor>(ex, protocol, native_socket)
229 {
230 }
231
232 /// Construct a basic_stream_socket on an existing native socket.
233 /**
234 * This constructor creates a stream socket object to hold an existing native
235 * socket.
236 *
237 * @param context An execution context which provides the I/O executor that
238 * the socket will use, by default, to dispatch handlers for any asynchronous
239 * operations performed on the socket.
240 *
241 * @param protocol An object specifying protocol parameters to be used.
242 *
243 * @param native_socket The new underlying socket implementation.
244 *
245 * @throws boost::system::system_error Thrown on failure.
246 */
247 template <typename ExecutionContext>
248 basic_stream_socket(ExecutionContext& context,
249 const protocol_type& protocol, const native_handle_type& native_socket,
250 constraint_t<
251 is_convertible<ExecutionContext&, execution_context&>::value
252 > = 0)
253 : basic_socket<Protocol, Executor>(context, protocol, native_socket)
254 {
255 }
256
257 /// Move-construct a basic_stream_socket from another.
258 /**
259 * This constructor moves a stream socket from one object to another.
260 *
261 * @param other The other basic_stream_socket object from which the move
262 * will occur.
263 *
264 * @note Following the move, the moved-from object is in the same state as if
265 * constructed using the @c basic_stream_socket(const executor_type&)
266 * constructor.
267 */
268 basic_stream_socket(basic_stream_socket&& other) noexcept
269 : basic_socket<Protocol, Executor>(std::move(other))
270 {
271 }
272
273 /// Move-assign a basic_stream_socket from another.
274 /**
275 * This assignment operator moves a stream socket from one object to another.
276 *
277 * @param other The other basic_stream_socket object from which the move
278 * will occur.
279 *
280 * @note Following the move, the moved-from object is in the same state as if
281 * constructed using the @c basic_stream_socket(const executor_type&)
282 * constructor.
283 */
284 basic_stream_socket& operator=(basic_stream_socket&& other)
285 {
286 basic_socket<Protocol, Executor>::operator=(std::move(other));
287 return *this;
288 }
289
290 /// Move-construct a basic_stream_socket from a socket of another protocol
291 /// type.
292 /**
293 * This constructor moves a stream socket from one object to another.
294 *
295 * @param other The other basic_stream_socket object from which the move
296 * will occur.
297 *
298 * @note Following the move, the moved-from object is in the same state as if
299 * constructed using the @c basic_stream_socket(const executor_type&)
300 * constructor.
301 */
302 template <typename Protocol1, typename Executor1>
303 basic_stream_socket(basic_stream_socket<Protocol1, Executor1>&& other,
304 constraint_t<
305 is_convertible<Protocol1, Protocol>::value
306 && is_convertible<Executor1, Executor>::value
307 > = 0)
308 : basic_socket<Protocol, Executor>(std::move(other))
309 {
310 }
311
312 /// Move-assign a basic_stream_socket from a socket of another protocol type.
313 /**
314 * This assignment operator moves a stream socket from one object to another.
315 *
316 * @param other The other basic_stream_socket object from which the move
317 * will occur.
318 *
319 * @note Following the move, the moved-from object is in the same state as if
320 * constructed using the @c basic_stream_socket(const executor_type&)
321 * constructor.
322 */
323 template <typename Protocol1, typename Executor1>
324 constraint_t<
325 is_convertible<Protocol1, Protocol>::value
326 && is_convertible<Executor1, Executor>::value,
327 basic_stream_socket&
328 > operator=(basic_stream_socket<Protocol1, Executor1>&& other)
329 {
330 basic_socket<Protocol, Executor>::operator=(std::move(other));
331 return *this;
332 }
333
334 /// Destroys the socket.
335 /**
336 * This function destroys the socket, cancelling any outstanding asynchronous
337 * operations associated with the socket as if by calling @c cancel.
338 */
339 ~basic_stream_socket()
340 {
341 }
342
343 /// Send some data on the socket.
344 /**
345 * This function is used to send data on the stream socket. The function
346 * call will block until one or more bytes of the data has been sent
347 * successfully, or an until error occurs.
348 *
349 * @param buffers One or more data buffers to be sent on the socket.
350 *
351 * @returns The number of bytes sent.
352 *
353 * @throws boost::system::system_error Thrown on failure.
354 *
355 * @note The send operation may not transmit all of the data to the peer.
356 * Consider using the @ref write function if you need to ensure that all data
357 * is written before the blocking operation completes.
358 *
359 * @par Example
360 * To send a single data buffer use the @ref buffer function as follows:
361 * @code
362 * socket.send(boost::asio::buffer(data, size));
363 * @endcode
364 * See the @ref buffer documentation for information on sending multiple
365 * buffers in one go, and how to use it with arrays, boost::array or
366 * std::vector.
367 */
368 template <typename ConstBufferSequence>
369 std::size_t send(const ConstBufferSequence& buffers)
370 {
371 boost::system::error_code ec;
372 std::size_t s = this->impl_.get_service().send(
373 this->impl_.get_implementation(), buffers, 0, ec);
374 boost::asio::detail::throw_error(err: ec, location: "send");
375 return s;
376 }
377
378 /// Send some data on the socket.
379 /**
380 * This function is used to send data on the stream socket. The function
381 * call will block until one or more bytes of the data has been sent
382 * successfully, or an until error occurs.
383 *
384 * @param buffers One or more data buffers to be sent on the socket.
385 *
386 * @param flags Flags specifying how the send call is to be made.
387 *
388 * @returns The number of bytes sent.
389 *
390 * @throws boost::system::system_error Thrown on failure.
391 *
392 * @note The send operation may not transmit all of the data to the peer.
393 * Consider using the @ref write function if you need to ensure that all data
394 * is written before the blocking operation completes.
395 *
396 * @par Example
397 * To send a single data buffer use the @ref buffer function as follows:
398 * @code
399 * socket.send(boost::asio::buffer(data, size), 0);
400 * @endcode
401 * See the @ref buffer documentation for information on sending multiple
402 * buffers in one go, and how to use it with arrays, boost::array or
403 * std::vector.
404 */
405 template <typename ConstBufferSequence>
406 std::size_t send(const ConstBufferSequence& buffers,
407 socket_base::message_flags flags)
408 {
409 boost::system::error_code ec;
410 std::size_t s = this->impl_.get_service().send(
411 this->impl_.get_implementation(), buffers, flags, ec);
412 boost::asio::detail::throw_error(err: ec, location: "send");
413 return s;
414 }
415
416 /// Send some data on the socket.
417 /**
418 * This function is used to send data on the stream socket. The function
419 * call will block until one or more bytes of the data has been sent
420 * successfully, or an until error occurs.
421 *
422 * @param buffers One or more data buffers to be sent on the socket.
423 *
424 * @param flags Flags specifying how the send call is to be made.
425 *
426 * @param ec Set to indicate what error occurred, if any.
427 *
428 * @returns The number of bytes sent. Returns 0 if an error occurred.
429 *
430 * @note The send operation may not transmit all of the data to the peer.
431 * Consider using the @ref write function if you need to ensure that all data
432 * is written before the blocking operation completes.
433 */
434 template <typename ConstBufferSequence>
435 std::size_t send(const ConstBufferSequence& buffers,
436 socket_base::message_flags flags, boost::system::error_code& ec)
437 {
438 return this->impl_.get_service().send(
439 this->impl_.get_implementation(), buffers, flags, ec);
440 }
441
442 /// Start an asynchronous send.
443 /**
444 * This function is used to asynchronously send data on the stream socket.
445 * It is an initiating function for an @ref asynchronous_operation, and always
446 * returns immediately.
447 *
448 * @param buffers One or more data buffers to be sent on the socket. Although
449 * the buffers object may be copied as necessary, ownership of the underlying
450 * memory blocks is retained by the caller, which must guarantee that they
451 * remain valid until the completion handler is called.
452 *
453 * @param token The @ref completion_token that will be used to produce a
454 * completion handler, which will be called when the send completes.
455 * Potential completion tokens include @ref use_future, @ref use_awaitable,
456 * @ref yield_context, or a function object with the correct completion
457 * signature. The function signature of the completion handler must be:
458 * @code void handler(
459 * const boost::system::error_code& error, // Result of operation.
460 * std::size_t bytes_transferred // Number of bytes sent.
461 * ); @endcode
462 * Regardless of whether the asynchronous operation completes immediately or
463 * not, the completion handler will not be invoked from within this function.
464 * On immediate completion, invocation of the handler will be performed in a
465 * manner equivalent to using boost::asio::post().
466 *
467 * @par Completion Signature
468 * @code void(boost::system::error_code, std::size_t) @endcode
469 *
470 * @note The send operation may not transmit all of the data to the peer.
471 * Consider using the @ref async_write function if you need to ensure that all
472 * data is written before the asynchronous operation completes.
473 *
474 * @par Example
475 * To send a single data buffer use the @ref buffer function as follows:
476 * @code
477 * socket.async_send(boost::asio::buffer(data, size), handler);
478 * @endcode
479 * See the @ref buffer documentation for information on sending multiple
480 * buffers in one go, and how to use it with arrays, boost::array or
481 * std::vector.
482 *
483 * @par Per-Operation Cancellation
484 * On POSIX or Windows operating systems, this asynchronous operation supports
485 * cancellation for the following boost::asio::cancellation_type values:
486 *
487 * @li @c cancellation_type::terminal
488 *
489 * @li @c cancellation_type::partial
490 *
491 * @li @c cancellation_type::total
492 */
493 template <typename ConstBufferSequence,
494 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
495 std::size_t)) WriteToken = default_completion_token_t<executor_type>>
496 auto async_send(const ConstBufferSequence& buffers,
497 WriteToken&& token = default_completion_token_t<executor_type>())
498 -> decltype(
499 async_initiate<WriteToken,
500 void (boost::system::error_code, std::size_t)>(
501 declval<initiate_async_send>(), token,
502 buffers, socket_base::message_flags(0)))
503 {
504 return async_initiate<WriteToken,
505 void (boost::system::error_code, std::size_t)>(
506 initiate_async_send(this), token,
507 buffers, socket_base::message_flags(0));
508 }
509
510 /// Start an asynchronous send.
511 /**
512 * This function is used to asynchronously send data on the stream socket.
513 * It is an initiating function for an @ref asynchronous_operation, and always
514 * returns immediately.
515 *
516 * @param buffers One or more data buffers to be sent on the socket. Although
517 * the buffers object may be copied as necessary, ownership of the underlying
518 * memory blocks is retained by the caller, which must guarantee that they
519 * remain valid until the completion handler is called.
520 *
521 * @param flags Flags specifying how the send call is to be made.
522 *
523 * @param token The @ref completion_token that will be used to produce a
524 * completion handler, which will be called when the send completes.
525 * Potential completion tokens include @ref use_future, @ref use_awaitable,
526 * @ref yield_context, or a function object with the correct completion
527 * signature. The function signature of the completion handler must be:
528 * @code void handler(
529 * const boost::system::error_code& error, // Result of operation.
530 * std::size_t bytes_transferred // Number of bytes sent.
531 * ); @endcode
532 * Regardless of whether the asynchronous operation completes immediately or
533 * not, the completion handler will not be invoked from within this function.
534 * On immediate completion, invocation of the handler will be performed in a
535 * manner equivalent to using boost::asio::post().
536 *
537 * @par Completion Signature
538 * @code void(boost::system::error_code, std::size_t) @endcode
539 *
540 * @note The send operation may not transmit all of the data to the peer.
541 * Consider using the @ref async_write function if you need to ensure that all
542 * data is written before the asynchronous operation completes.
543 *
544 * @par Example
545 * To send a single data buffer use the @ref buffer function as follows:
546 * @code
547 * socket.async_send(boost::asio::buffer(data, size), 0, handler);
548 * @endcode
549 * See the @ref buffer documentation for information on sending multiple
550 * buffers in one go, and how to use it with arrays, boost::array or
551 * std::vector.
552 *
553 * @par Per-Operation Cancellation
554 * On POSIX or Windows operating systems, this asynchronous operation supports
555 * cancellation for the following boost::asio::cancellation_type values:
556 *
557 * @li @c cancellation_type::terminal
558 *
559 * @li @c cancellation_type::partial
560 *
561 * @li @c cancellation_type::total
562 */
563 template <typename ConstBufferSequence,
564 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
565 std::size_t)) WriteToken = default_completion_token_t<executor_type>>
566 auto async_send(const ConstBufferSequence& buffers,
567 socket_base::message_flags flags,
568 WriteToken&& token = default_completion_token_t<executor_type>())
569 -> decltype(
570 async_initiate<WriteToken,
571 void (boost::system::error_code, std::size_t)>(
572 declval<initiate_async_send>(), token, buffers, flags))
573 {
574 return async_initiate<WriteToken,
575 void (boost::system::error_code, std::size_t)>(
576 initiate_async_send(this), token, buffers, flags);
577 }
578
579 /// Receive some data on the socket.
580 /**
581 * This function is used to receive data on the stream socket. The function
582 * call will block until one or more bytes of data has been received
583 * successfully, or until an error occurs.
584 *
585 * @param buffers One or more buffers into which the data will be received.
586 *
587 * @returns The number of bytes received.
588 *
589 * @throws boost::system::system_error Thrown on failure. An error code of
590 * boost::asio::error::eof indicates that the connection was closed by the
591 * peer.
592 *
593 * @note The receive operation may not receive all of the requested number of
594 * bytes. Consider using the @ref read function if you need to ensure that the
595 * requested amount of data is read before the blocking operation completes.
596 *
597 * @par Example
598 * To receive into a single data buffer use the @ref buffer function as
599 * follows:
600 * @code
601 * socket.receive(boost::asio::buffer(data, size));
602 * @endcode
603 * See the @ref buffer documentation for information on receiving into
604 * multiple buffers in one go, and how to use it with arrays, boost::array or
605 * std::vector.
606 */
607 template <typename MutableBufferSequence>
608 std::size_t receive(const MutableBufferSequence& buffers)
609 {
610 boost::system::error_code ec;
611 std::size_t s = this->impl_.get_service().receive(
612 this->impl_.get_implementation(), buffers, 0, ec);
613 boost::asio::detail::throw_error(err: ec, location: "receive");
614 return s;
615 }
616
617 /// Receive some data on the socket.
618 /**
619 * This function is used to receive data on the stream socket. The function
620 * call will block until one or more bytes of data has been received
621 * successfully, or until an error occurs.
622 *
623 * @param buffers One or more buffers into which the data will be received.
624 *
625 * @param flags Flags specifying how the receive call is to be made.
626 *
627 * @returns The number of bytes received.
628 *
629 * @throws boost::system::system_error Thrown on failure. An error code of
630 * boost::asio::error::eof indicates that the connection was closed by the
631 * peer.
632 *
633 * @note The receive operation may not receive all of the requested number of
634 * bytes. Consider using the @ref read function if you need to ensure that the
635 * requested amount of data is read before the blocking operation completes.
636 *
637 * @par Example
638 * To receive into a single data buffer use the @ref buffer function as
639 * follows:
640 * @code
641 * socket.receive(boost::asio::buffer(data, size), 0);
642 * @endcode
643 * See the @ref buffer documentation for information on receiving into
644 * multiple buffers in one go, and how to use it with arrays, boost::array or
645 * std::vector.
646 */
647 template <typename MutableBufferSequence>
648 std::size_t receive(const MutableBufferSequence& buffers,
649 socket_base::message_flags flags)
650 {
651 boost::system::error_code ec;
652 std::size_t s = this->impl_.get_service().receive(
653 this->impl_.get_implementation(), buffers, flags, ec);
654 boost::asio::detail::throw_error(err: ec, location: "receive");
655 return s;
656 }
657
658 /// Receive some data on a connected socket.
659 /**
660 * This function is used to receive data on the stream socket. The function
661 * call will block until one or more bytes of data has been received
662 * successfully, or until an error occurs.
663 *
664 * @param buffers One or more buffers into which the data will be received.
665 *
666 * @param flags Flags specifying how the receive call is to be made.
667 *
668 * @param ec Set to indicate what error occurred, if any.
669 *
670 * @returns The number of bytes received. Returns 0 if an error occurred.
671 *
672 * @note The receive operation may not receive all of the requested number of
673 * bytes. Consider using the @ref read function if you need to ensure that the
674 * requested amount of data is read before the blocking operation completes.
675 */
676 template <typename MutableBufferSequence>
677 std::size_t receive(const MutableBufferSequence& buffers,
678 socket_base::message_flags flags, boost::system::error_code& ec)
679 {
680 return this->impl_.get_service().receive(
681 this->impl_.get_implementation(), buffers, flags, ec);
682 }
683
684 /// Start an asynchronous receive.
685 /**
686 * This function is used to asynchronously receive data from the stream
687 * socket. It is an initiating function for an @ref asynchronous_operation,
688 * and always returns immediately.
689 *
690 * @param buffers One or more buffers into which the data will be received.
691 * Although the buffers object may be copied as necessary, ownership of the
692 * underlying memory blocks is retained by the caller, which must guarantee
693 * that they remain valid until the completion handler is called.
694 *
695 * @param token The @ref completion_token that will be used to produce a
696 * completion handler, which will be called when the receive completes.
697 * Potential completion tokens include @ref use_future, @ref use_awaitable,
698 * @ref yield_context, or a function object with the correct completion
699 * signature. The function signature of the completion handler must be:
700 * @code void handler(
701 * const boost::system::error_code& error, // Result of operation.
702 * std::size_t bytes_transferred // Number of bytes received.
703 * ); @endcode
704 * Regardless of whether the asynchronous operation completes immediately or
705 * not, the completion handler will not be invoked from within this function.
706 * On immediate completion, invocation of the handler will be performed in a
707 * manner equivalent to using boost::asio::post().
708 *
709 * @par Completion Signature
710 * @code void(boost::system::error_code, std::size_t) @endcode
711 *
712 * @note The receive operation may not receive all of the requested number of
713 * bytes. Consider using the @ref async_read function if you need to ensure
714 * that the requested amount of data is received before the asynchronous
715 * operation completes.
716 *
717 * @par Example
718 * To receive into a single data buffer use the @ref buffer function as
719 * follows:
720 * @code
721 * socket.async_receive(boost::asio::buffer(data, size), handler);
722 * @endcode
723 * See the @ref buffer documentation for information on receiving into
724 * multiple buffers in one go, and how to use it with arrays, boost::array or
725 * std::vector.
726 *
727 * @par Per-Operation Cancellation
728 * On POSIX or Windows operating systems, this asynchronous operation supports
729 * cancellation for the following boost::asio::cancellation_type values:
730 *
731 * @li @c cancellation_type::terminal
732 *
733 * @li @c cancellation_type::partial
734 *
735 * @li @c cancellation_type::total
736 */
737 template <typename MutableBufferSequence,
738 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
739 std::size_t)) ReadToken = default_completion_token_t<executor_type>>
740 auto async_receive(const MutableBufferSequence& buffers,
741 ReadToken&& token = default_completion_token_t<executor_type>())
742 -> decltype(
743 async_initiate<ReadToken,
744 void (boost::system::error_code, std::size_t)>(
745 declval<initiate_async_receive>(), token,
746 buffers, socket_base::message_flags(0)))
747 {
748 return async_initiate<ReadToken,
749 void (boost::system::error_code, std::size_t)>(
750 initiate_async_receive(this), token,
751 buffers, socket_base::message_flags(0));
752 }
753
754 /// Start an asynchronous receive.
755 /**
756 * This function is used to asynchronously receive data from the stream
757 * socket. It is an initiating function for an @ref asynchronous_operation,
758 * and always returns immediately.
759 *
760 * @param buffers One or more buffers into which the data will be received.
761 * Although the buffers object may be copied as necessary, ownership of the
762 * underlying memory blocks is retained by the caller, which must guarantee
763 * that they remain valid until the completion handler is called.
764 *
765 * @param flags Flags specifying how the receive call is to be made.
766 *
767 * @param token The @ref completion_token that will be used to produce a
768 * completion handler, which will be called when the receive completes.
769 * Potential completion tokens include @ref use_future, @ref use_awaitable,
770 * @ref yield_context, or a function object with the correct completion
771 * signature. The function signature of the completion handler must be:
772 * @code void handler(
773 * const boost::system::error_code& error, // Result of operation.
774 * std::size_t bytes_transferred // Number of bytes received.
775 * ); @endcode
776 * Regardless of whether the asynchronous operation completes immediately or
777 * not, the completion handler will not be invoked from within this function.
778 * On immediate completion, invocation of the handler will be performed in a
779 * manner equivalent to using boost::asio::post().
780 *
781 * @par Completion Signature
782 * @code void(boost::system::error_code, std::size_t) @endcode
783 *
784 * @note The receive operation may not receive all of the requested number of
785 * bytes. Consider using the @ref async_read function if you need to ensure
786 * that the requested amount of data is received before the asynchronous
787 * operation completes.
788 *
789 * @par Example
790 * To receive into a single data buffer use the @ref buffer function as
791 * follows:
792 * @code
793 * socket.async_receive(boost::asio::buffer(data, size), 0, handler);
794 * @endcode
795 * See the @ref buffer documentation for information on receiving into
796 * multiple buffers in one go, and how to use it with arrays, boost::array or
797 * std::vector.
798 *
799 * @par Per-Operation Cancellation
800 * On POSIX or Windows operating systems, this asynchronous operation supports
801 * cancellation for the following boost::asio::cancellation_type values:
802 *
803 * @li @c cancellation_type::terminal
804 *
805 * @li @c cancellation_type::partial
806 *
807 * @li @c cancellation_type::total
808 */
809 template <typename MutableBufferSequence,
810 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
811 std::size_t)) ReadToken = default_completion_token_t<executor_type>>
812 auto async_receive(const MutableBufferSequence& buffers,
813 socket_base::message_flags flags,
814 ReadToken&& token = default_completion_token_t<executor_type>())
815 -> decltype(
816 async_initiate<ReadToken,
817 void (boost::system::error_code, std::size_t)>(
818 declval<initiate_async_receive>(), token, buffers, flags))
819 {
820 return async_initiate<ReadToken,
821 void (boost::system::error_code, std::size_t)>(
822 initiate_async_receive(this), token, buffers, flags);
823 }
824
825 /// Write some data to the socket.
826 /**
827 * This function is used to write data to the stream socket. The function call
828 * will block until one or more bytes of the data has been written
829 * successfully, or until an error occurs.
830 *
831 * @param buffers One or more data buffers to be written to the socket.
832 *
833 * @returns The number of bytes written.
834 *
835 * @throws boost::system::system_error Thrown on failure. An error code of
836 * boost::asio::error::eof indicates that the connection was closed by the
837 * peer.
838 *
839 * @note The write_some operation may not transmit all of the data to the
840 * peer. Consider using the @ref write function if you need to ensure that
841 * all data is written before the blocking operation completes.
842 *
843 * @par Example
844 * To write a single data buffer use the @ref buffer function as follows:
845 * @code
846 * socket.write_some(boost::asio::buffer(data, size));
847 * @endcode
848 * See the @ref buffer documentation for information on writing multiple
849 * buffers in one go, and how to use it with arrays, boost::array or
850 * std::vector.
851 */
852 template <typename ConstBufferSequence>
853 std::size_t write_some(const ConstBufferSequence& buffers)
854 {
855 boost::system::error_code ec;
856 std::size_t s = this->impl_.get_service().send(
857 this->impl_.get_implementation(), buffers, 0, ec);
858 boost::asio::detail::throw_error(err: ec, location: "write_some");
859 return s;
860 }
861
862 /// Write some data to the socket.
863 /**
864 * This function is used to write data to the stream socket. The function call
865 * will block until one or more bytes of the data has been written
866 * successfully, or until an error occurs.
867 *
868 * @param buffers One or more data buffers to be written to the socket.
869 *
870 * @param ec Set to indicate what error occurred, if any.
871 *
872 * @returns The number of bytes written. Returns 0 if an error occurred.
873 *
874 * @note The write_some operation may not transmit all of the data to the
875 * peer. Consider using the @ref write function if you need to ensure that
876 * all data is written before the blocking operation completes.
877 */
878 template <typename ConstBufferSequence>
879 std::size_t write_some(const ConstBufferSequence& buffers,
880 boost::system::error_code& ec)
881 {
882 return this->impl_.get_service().send(
883 this->impl_.get_implementation(), buffers, 0, ec);
884 }
885
886 /// Start an asynchronous write.
887 /**
888 * This function is used to asynchronously write data to the stream socket.
889 * It is an initiating function for an @ref asynchronous_operation, and always
890 * returns immediately.
891 *
892 * @param buffers One or more data buffers to be written to the socket.
893 * Although the buffers object may be copied as necessary, ownership of the
894 * underlying memory blocks is retained by the caller, which must guarantee
895 * that they remain valid until the completion handler is called.
896 *
897 * @param token The @ref completion_token that will be used to produce a
898 * completion handler, which will be called when the write completes.
899 * Potential completion tokens include @ref use_future, @ref use_awaitable,
900 * @ref yield_context, or a function object with the correct completion
901 * signature. The function signature of the completion handler must be:
902 * @code void handler(
903 * const boost::system::error_code& error, // Result of operation.
904 * std::size_t bytes_transferred // Number of bytes written.
905 * ); @endcode
906 * Regardless of whether the asynchronous operation completes immediately or
907 * not, the completion handler will not be invoked from within this function.
908 * On immediate completion, invocation of the handler will be performed in a
909 * manner equivalent to using boost::asio::post().
910 *
911 * @par Completion Signature
912 * @code void(boost::system::error_code, std::size_t) @endcode
913 *
914 * @note The write operation may not transmit all of the data to the peer.
915 * Consider using the @ref async_write function if you need to ensure that all
916 * data is written before the asynchronous operation completes.
917 *
918 * @par Example
919 * To write a single data buffer use the @ref buffer function as follows:
920 * @code
921 * socket.async_write_some(boost::asio::buffer(data, size), handler);
922 * @endcode
923 * See the @ref buffer documentation for information on writing multiple
924 * buffers in one go, and how to use it with arrays, boost::array or
925 * std::vector.
926 *
927 * @par Per-Operation Cancellation
928 * On POSIX or Windows operating systems, this asynchronous operation supports
929 * cancellation for the following boost::asio::cancellation_type values:
930 *
931 * @li @c cancellation_type::terminal
932 *
933 * @li @c cancellation_type::partial
934 *
935 * @li @c cancellation_type::total
936 */
937 template <typename ConstBufferSequence,
938 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
939 std::size_t)) WriteToken = default_completion_token_t<executor_type>>
940 auto async_write_some(const ConstBufferSequence& buffers,
941 WriteToken&& token = default_completion_token_t<executor_type>())
942 -> decltype(
943 async_initiate<WriteToken,
944 void (boost::system::error_code, std::size_t)>(
945 declval<initiate_async_send>(), token,
946 buffers, socket_base::message_flags(0)))
947 {
948 return async_initiate<WriteToken,
949 void (boost::system::error_code, std::size_t)>(
950 initiate_async_send(this), token,
951 buffers, socket_base::message_flags(0));
952 }
953
954 /// Read some data from the socket.
955 /**
956 * This function is used to read data from the stream socket. The function
957 * call will block until one or more bytes of data has been read successfully,
958 * or until an error occurs.
959 *
960 * @param buffers One or more buffers into which the data will be read.
961 *
962 * @returns The number of bytes read.
963 *
964 * @throws boost::system::system_error Thrown on failure. An error code of
965 * boost::asio::error::eof indicates that the connection was closed by the
966 * peer.
967 *
968 * @note The read_some operation may not read all of the requested number of
969 * bytes. Consider using the @ref read function if you need to ensure that
970 * the requested amount of data is read before the blocking operation
971 * completes.
972 *
973 * @par Example
974 * To read into a single data buffer use the @ref buffer function as follows:
975 * @code
976 * socket.read_some(boost::asio::buffer(data, size));
977 * @endcode
978 * See the @ref buffer documentation for information on reading into multiple
979 * buffers in one go, and how to use it with arrays, boost::array or
980 * std::vector.
981 */
982 template <typename MutableBufferSequence>
983 std::size_t read_some(const MutableBufferSequence& buffers)
984 {
985 boost::system::error_code ec;
986 std::size_t s = this->impl_.get_service().receive(
987 this->impl_.get_implementation(), buffers, 0, ec);
988 boost::asio::detail::throw_error(err: ec, location: "read_some");
989 return s;
990 }
991
992 /// Read some data from the socket.
993 /**
994 * This function is used to read data from the stream socket. The function
995 * call will block until one or more bytes of data has been read successfully,
996 * or until an error occurs.
997 *
998 * @param buffers One or more buffers into which the data will be read.
999 *
1000 * @param ec Set to indicate what error occurred, if any.
1001 *
1002 * @returns The number of bytes read. Returns 0 if an error occurred.
1003 *
1004 * @note The read_some operation may not read all of the requested number of
1005 * bytes. Consider using the @ref read function if you need to ensure that
1006 * the requested amount of data is read before the blocking operation
1007 * completes.
1008 */
1009 template <typename MutableBufferSequence>
1010 std::size_t read_some(const MutableBufferSequence& buffers,
1011 boost::system::error_code& ec)
1012 {
1013 return this->impl_.get_service().receive(
1014 this->impl_.get_implementation(), buffers, 0, ec);
1015 }
1016
1017 /// Start an asynchronous read.
1018 /**
1019 * This function is used to asynchronously read data from the stream socket.
1020 * socket. It is an initiating function for an @ref asynchronous_operation,
1021 * and always returns immediately.
1022 *
1023 * @param buffers One or more buffers into which the data will be read.
1024 * Although the buffers object may be copied as necessary, ownership of the
1025 * underlying memory blocks is retained by the caller, which must guarantee
1026 * that they remain valid until the completion handler is called.
1027 *
1028 * @param token The @ref completion_token that will be used to produce a
1029 * completion handler, which will be called when the read completes.
1030 * Potential completion tokens include @ref use_future, @ref use_awaitable,
1031 * @ref yield_context, or a function object with the correct completion
1032 * signature. The function signature of the completion handler must be:
1033 * @code void handler(
1034 * const boost::system::error_code& error, // Result of operation.
1035 * std::size_t bytes_transferred // Number of bytes read.
1036 * ); @endcode
1037 * Regardless of whether the asynchronous operation completes immediately or
1038 * not, the completion handler will not be invoked from within this function.
1039 * On immediate completion, invocation of the handler will be performed in a
1040 * manner equivalent to using boost::asio::post().
1041 *
1042 * @par Completion Signature
1043 * @code void(boost::system::error_code, std::size_t) @endcode
1044 *
1045 * @note The read operation may not read all of the requested number of bytes.
1046 * Consider using the @ref async_read function if you need to ensure that the
1047 * requested amount of data is read before the asynchronous operation
1048 * completes.
1049 *
1050 * @par Example
1051 * To read into a single data buffer use the @ref buffer function as follows:
1052 * @code
1053 * socket.async_read_some(boost::asio::buffer(data, size), handler);
1054 * @endcode
1055 * See the @ref buffer documentation for information on reading into multiple
1056 * buffers in one go, and how to use it with arrays, boost::array or
1057 * std::vector.
1058 *
1059 * @par Per-Operation Cancellation
1060 * On POSIX or Windows operating systems, this asynchronous operation supports
1061 * cancellation for the following boost::asio::cancellation_type values:
1062 *
1063 * @li @c cancellation_type::terminal
1064 *
1065 * @li @c cancellation_type::partial
1066 *
1067 * @li @c cancellation_type::total
1068 */
1069 template <typename MutableBufferSequence,
1070 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1071 std::size_t)) ReadToken = default_completion_token_t<executor_type>>
1072 auto async_read_some(const MutableBufferSequence& buffers,
1073 ReadToken&& token = default_completion_token_t<executor_type>())
1074 -> decltype(
1075 async_initiate<ReadToken,
1076 void (boost::system::error_code, std::size_t)>(
1077 declval<initiate_async_receive>(), token,
1078 buffers, socket_base::message_flags(0)))
1079 {
1080 return async_initiate<ReadToken,
1081 void (boost::system::error_code, std::size_t)>(
1082 initiate_async_receive(this), token,
1083 buffers, socket_base::message_flags(0));
1084 }
1085
1086private:
1087 // Disallow copying and assignment.
1088 basic_stream_socket(const basic_stream_socket&) = delete;
1089 basic_stream_socket& operator=(const basic_stream_socket&) = delete;
1090
1091 class initiate_async_send
1092 {
1093 public:
1094 typedef Executor executor_type;
1095
1096 explicit initiate_async_send(basic_stream_socket* self)
1097 : self_(self)
1098 {
1099 }
1100
1101 const executor_type& get_executor() const noexcept
1102 {
1103 return self_->get_executor();
1104 }
1105
1106 template <typename WriteHandler, typename ConstBufferSequence>
1107 void operator()(WriteHandler&& handler,
1108 const ConstBufferSequence& buffers,
1109 socket_base::message_flags flags) const
1110 {
1111 // If you get an error on the following line it means that your handler
1112 // does not meet the documented type requirements for a WriteHandler.
1113 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
1114
1115 detail::non_const_lvalue<WriteHandler> handler2(handler);
1116 self_->impl_.get_service().async_send(
1117 self_->impl_.get_implementation(), buffers, flags,
1118 handler2.value, self_->impl_.get_executor());
1119 }
1120
1121 private:
1122 basic_stream_socket* self_;
1123 };
1124
1125 class initiate_async_receive
1126 {
1127 public:
1128 typedef Executor executor_type;
1129
1130 explicit initiate_async_receive(basic_stream_socket* self)
1131 : self_(self)
1132 {
1133 }
1134
1135 const executor_type& get_executor() const noexcept
1136 {
1137 return self_->get_executor();
1138 }
1139
1140 template <typename ReadHandler, typename MutableBufferSequence>
1141 void operator()(ReadHandler&& handler,
1142 const MutableBufferSequence& buffers,
1143 socket_base::message_flags flags) const
1144 {
1145 // If you get an error on the following line it means that your handler
1146 // does not meet the documented type requirements for a ReadHandler.
1147 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
1148
1149 detail::non_const_lvalue<ReadHandler> handler2(handler);
1150 self_->impl_.get_service().async_receive(
1151 self_->impl_.get_implementation(), buffers, flags,
1152 handler2.value, self_->impl_.get_executor());
1153 }
1154
1155 private:
1156 basic_stream_socket* self_;
1157 };
1158};
1159
1160} // namespace asio
1161} // namespace boost
1162
1163#include <boost/asio/detail/pop_options.hpp>
1164
1165#endif // BOOST_ASIO_BASIC_STREAM_SOCKET_HPP
1166

source code of boost/libs/asio/include/boost/asio/basic_stream_socket.hpp