]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/asio/basic_seq_packet_socket.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / asio / basic_seq_packet_socket.hpp
1 //
2 // basic_seq_packet_socket.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2020 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_SEQ_PACKET_SOCKET_HPP
12 #define BOOST_ASIO_BASIC_SEQ_PACKET_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/basic_socket.hpp>
21 #include <boost/asio/detail/handler_type_requirements.hpp>
22 #include <boost/asio/detail/throw_error.hpp>
23 #include <boost/asio/error.hpp>
24
25 #include <boost/asio/detail/push_options.hpp>
26
27 namespace boost {
28 namespace asio {
29
30 #if !defined(BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL)
31 #define BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL
32
33 // Forward declaration with defaulted arguments.
34 template <typename Protocol, typename Executor = any_io_executor>
35 class basic_seq_packet_socket;
36
37 #endif // !defined(BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL)
38
39 /// Provides sequenced packet socket functionality.
40 /**
41 * The basic_seq_packet_socket class template provides asynchronous and blocking
42 * sequenced packet socket functionality.
43 *
44 * @par Thread Safety
45 * @e Distinct @e objects: Safe.@n
46 * @e Shared @e objects: Unsafe.
47 */
48 template <typename Protocol, typename Executor>
49 class basic_seq_packet_socket
50 : public basic_socket<Protocol, Executor>
51 {
52 public:
53 /// The type of the executor associated with the object.
54 typedef Executor executor_type;
55
56 /// Rebinds the socket type to another executor.
57 template <typename Executor1>
58 struct rebind_executor
59 {
60 /// The socket type when rebound to the specified executor.
61 typedef basic_seq_packet_socket<Protocol, Executor1> other;
62 };
63
64 /// The native representation of a socket.
65 #if defined(GENERATING_DOCUMENTATION)
66 typedef implementation_defined native_handle_type;
67 #else
68 typedef typename basic_socket<Protocol,
69 Executor>::native_handle_type native_handle_type;
70 #endif
71
72 /// The protocol type.
73 typedef Protocol protocol_type;
74
75 /// The endpoint type.
76 typedef typename Protocol::endpoint endpoint_type;
77
78 /// Construct a basic_seq_packet_socket without opening it.
79 /**
80 * This constructor creates a sequenced packet socket without opening it. The
81 * socket needs to be opened and then connected or accepted before data can
82 * be sent or received on it.
83 *
84 * @param ex The I/O executor that the socket will use, by default, to
85 * dispatch handlers for any asynchronous operations performed on the socket.
86 */
87 explicit basic_seq_packet_socket(const executor_type& ex)
88 : basic_socket<Protocol, Executor>(ex)
89 {
90 }
91
92 /// Construct a basic_seq_packet_socket without opening it.
93 /**
94 * This constructor creates a sequenced packet socket without opening it. The
95 * socket needs to be opened and then connected or accepted before data can
96 * be sent or received on it.
97 *
98 * @param context An execution context which provides the I/O executor that
99 * the socket will use, by default, to dispatch handlers for any asynchronous
100 * operations performed on the socket.
101 */
102 template <typename ExecutionContext>
103 explicit basic_seq_packet_socket(ExecutionContext& context,
104 typename enable_if<
105 is_convertible<ExecutionContext&, execution_context&>::value
106 >::type* = 0)
107 : basic_socket<Protocol, Executor>(context)
108 {
109 }
110
111 /// Construct and open a basic_seq_packet_socket.
112 /**
113 * This constructor creates and opens a sequenced_packet socket. The socket
114 * needs to be connected or accepted before data can be sent or received on
115 * it.
116 *
117 * @param ex The I/O executor that the socket will use, by default, to
118 * dispatch handlers for any asynchronous operations performed on the socket.
119 *
120 * @param protocol An object specifying protocol parameters to be used.
121 *
122 * @throws boost::system::system_error Thrown on failure.
123 */
124 basic_seq_packet_socket(const executor_type& ex,
125 const protocol_type& protocol)
126 : basic_socket<Protocol, Executor>(ex, protocol)
127 {
128 }
129
130 /// Construct and open a basic_seq_packet_socket.
131 /**
132 * This constructor creates and opens a sequenced_packet socket. The socket
133 * needs to be connected or accepted before data can be sent or received on
134 * it.
135 *
136 * @param context An execution context which provides the I/O executor that
137 * the socket will use, by default, to dispatch handlers for any asynchronous
138 * operations performed on the socket.
139 *
140 * @param protocol An object specifying protocol parameters to be used.
141 *
142 * @throws boost::system::system_error Thrown on failure.
143 */
144 template <typename ExecutionContext>
145 basic_seq_packet_socket(ExecutionContext& context,
146 const protocol_type& protocol,
147 typename enable_if<
148 is_convertible<ExecutionContext&, execution_context&>::value
149 >::type* = 0)
150 : basic_socket<Protocol, Executor>(context, protocol)
151 {
152 }
153
154 /// Construct a basic_seq_packet_socket, opening it and binding it to the
155 /// given local endpoint.
156 /**
157 * This constructor creates a sequenced packet socket and automatically opens
158 * it bound to the specified endpoint on the local machine. The protocol used
159 * is the protocol associated with the given endpoint.
160 *
161 * @param ex The I/O executor that the socket will use, by default, to
162 * dispatch handlers for any asynchronous operations performed on the socket.
163 *
164 * @param endpoint An endpoint on the local machine to which the sequenced
165 * packet socket will be bound.
166 *
167 * @throws boost::system::system_error Thrown on failure.
168 */
169 basic_seq_packet_socket(const executor_type& ex,
170 const endpoint_type& endpoint)
171 : basic_socket<Protocol, Executor>(ex, endpoint)
172 {
173 }
174
175 /// Construct a basic_seq_packet_socket, opening it and binding it to the
176 /// given local endpoint.
177 /**
178 * This constructor creates a sequenced packet socket and automatically opens
179 * it bound to the specified endpoint on the local machine. The protocol used
180 * is the protocol associated with the given endpoint.
181 *
182 * @param context An execution context which provides the I/O executor that
183 * the socket will use, by default, to dispatch handlers for any asynchronous
184 * operations performed on the socket.
185 *
186 * @param endpoint An endpoint on the local machine to which the sequenced
187 * packet socket will be bound.
188 *
189 * @throws boost::system::system_error Thrown on failure.
190 */
191 template <typename ExecutionContext>
192 basic_seq_packet_socket(ExecutionContext& context,
193 const endpoint_type& endpoint,
194 typename enable_if<
195 is_convertible<ExecutionContext&, execution_context&>::value
196 >::type* = 0)
197 : basic_socket<Protocol, Executor>(context, endpoint)
198 {
199 }
200
201 /// Construct a basic_seq_packet_socket on an existing native socket.
202 /**
203 * This constructor creates a sequenced packet socket object to hold an
204 * existing native socket.
205 *
206 * @param ex The I/O executor that the socket will use, by default, to
207 * dispatch handlers for any asynchronous operations performed on the socket.
208 *
209 * @param protocol An object specifying protocol parameters to be used.
210 *
211 * @param native_socket The new underlying socket implementation.
212 *
213 * @throws boost::system::system_error Thrown on failure.
214 */
215 basic_seq_packet_socket(const executor_type& ex,
216 const protocol_type& protocol, const native_handle_type& native_socket)
217 : basic_socket<Protocol, Executor>(ex, protocol, native_socket)
218 {
219 }
220
221 /// Construct a basic_seq_packet_socket on an existing native socket.
222 /**
223 * This constructor creates a sequenced packet socket object to hold an
224 * existing native socket.
225 *
226 * @param context An execution context which provides the I/O executor that
227 * the socket will use, by default, to dispatch handlers for any asynchronous
228 * operations performed on the socket.
229 *
230 * @param protocol An object specifying protocol parameters to be used.
231 *
232 * @param native_socket The new underlying socket implementation.
233 *
234 * @throws boost::system::system_error Thrown on failure.
235 */
236 template <typename ExecutionContext>
237 basic_seq_packet_socket(ExecutionContext& context,
238 const protocol_type& protocol, const native_handle_type& native_socket,
239 typename enable_if<
240 is_convertible<ExecutionContext&, execution_context&>::value
241 >::type* = 0)
242 : basic_socket<Protocol, Executor>(context, protocol, native_socket)
243 {
244 }
245
246 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
247 /// Move-construct a basic_seq_packet_socket from another.
248 /**
249 * This constructor moves a sequenced packet socket from one object to
250 * another.
251 *
252 * @param other The other basic_seq_packet_socket object from which the move
253 * will occur.
254 *
255 * @note Following the move, the moved-from object is in the same state as if
256 * constructed using the @c basic_seq_packet_socket(const executor_type&)
257 * constructor.
258 */
259 basic_seq_packet_socket(basic_seq_packet_socket&& other) BOOST_ASIO_NOEXCEPT
260 : basic_socket<Protocol, Executor>(std::move(other))
261 {
262 }
263
264 /// Move-assign a basic_seq_packet_socket from another.
265 /**
266 * This assignment operator moves a sequenced packet socket from one object to
267 * another.
268 *
269 * @param other The other basic_seq_packet_socket object from which the move
270 * will occur.
271 *
272 * @note Following the move, the moved-from object is in the same state as if
273 * constructed using the @c basic_seq_packet_socket(const executor_type&)
274 * constructor.
275 */
276 basic_seq_packet_socket& operator=(basic_seq_packet_socket&& other)
277 {
278 basic_socket<Protocol, Executor>::operator=(std::move(other));
279 return *this;
280 }
281
282 /// Move-construct a basic_seq_packet_socket from a socket of another protocol
283 /// type.
284 /**
285 * This constructor moves a sequenced packet socket from one object to
286 * another.
287 *
288 * @param other The other basic_seq_packet_socket object from which the move
289 * will occur.
290 *
291 * @note Following the move, the moved-from object is in the same state as if
292 * constructed using the @c basic_seq_packet_socket(const executor_type&)
293 * constructor.
294 */
295 template <typename Protocol1, typename Executor1>
296 basic_seq_packet_socket(basic_seq_packet_socket<Protocol1, Executor1>&& other,
297 typename enable_if<
298 is_convertible<Protocol1, Protocol>::value
299 && is_convertible<Executor1, Executor>::value
300 >::type* = 0)
301 : basic_socket<Protocol, Executor>(std::move(other))
302 {
303 }
304
305 /// Move-assign a basic_seq_packet_socket from a socket of another protocol
306 /// type.
307 /**
308 * This assignment operator moves a sequenced packet socket from one object to
309 * another.
310 *
311 * @param other The other basic_seq_packet_socket object from which the move
312 * will occur.
313 *
314 * @note Following the move, the moved-from object is in the same state as if
315 * constructed using the @c basic_seq_packet_socket(const executor_type&)
316 * constructor.
317 */
318 template <typename Protocol1, typename Executor1>
319 typename enable_if<
320 is_convertible<Protocol1, Protocol>::value
321 && is_convertible<Executor1, Executor>::value,
322 basic_seq_packet_socket&
323 >::type operator=(basic_seq_packet_socket<Protocol1, Executor1>&& other)
324 {
325 basic_socket<Protocol, Executor>::operator=(std::move(other));
326 return *this;
327 }
328 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
329
330 /// Destroys the socket.
331 /**
332 * This function destroys the socket, cancelling any outstanding asynchronous
333 * operations associated with the socket as if by calling @c cancel.
334 */
335 ~basic_seq_packet_socket()
336 {
337 }
338
339 /// Send some data on the socket.
340 /**
341 * This function is used to send data on the sequenced packet socket. The
342 * function call will block until the data has been sent successfully, or an
343 * until error occurs.
344 *
345 * @param buffers One or more data buffers to be sent on the socket.
346 *
347 * @param flags Flags specifying how the send call is to be made.
348 *
349 * @returns The number of bytes sent.
350 *
351 * @throws boost::system::system_error Thrown on failure.
352 *
353 * @par Example
354 * To send a single data buffer use the @ref buffer function as follows:
355 * @code
356 * socket.send(boost::asio::buffer(data, size), 0);
357 * @endcode
358 * See the @ref buffer documentation for information on sending multiple
359 * buffers in one go, and how to use it with arrays, boost::array or
360 * std::vector.
361 */
362 template <typename ConstBufferSequence>
363 std::size_t send(const ConstBufferSequence& buffers,
364 socket_base::message_flags flags)
365 {
366 boost::system::error_code ec;
367 std::size_t s = this->impl_.get_service().send(
368 this->impl_.get_implementation(), buffers, flags, ec);
369 boost::asio::detail::throw_error(ec, "send");
370 return s;
371 }
372
373 /// Send some data on the socket.
374 /**
375 * This function is used to send data on the sequenced packet socket. The
376 * function call will block the data has been sent successfully, or an until
377 * error occurs.
378 *
379 * @param buffers One or more data buffers to be sent on the socket.
380 *
381 * @param flags Flags specifying how the send call is to be made.
382 *
383 * @param ec Set to indicate what error occurred, if any.
384 *
385 * @returns The number of bytes sent. Returns 0 if an error occurred.
386 *
387 * @note The send operation may not transmit all of the data to the peer.
388 * Consider using the @ref write function if you need to ensure that all data
389 * is written before the blocking operation completes.
390 */
391 template <typename ConstBufferSequence>
392 std::size_t send(const ConstBufferSequence& buffers,
393 socket_base::message_flags flags, boost::system::error_code& ec)
394 {
395 return this->impl_.get_service().send(
396 this->impl_.get_implementation(), buffers, flags, ec);
397 }
398
399 /// Start an asynchronous send.
400 /**
401 * This function is used to asynchronously send data on the sequenced packet
402 * socket. The function call always returns immediately.
403 *
404 * @param buffers One or more data buffers to be sent on the socket. Although
405 * the buffers object may be copied as necessary, ownership of the underlying
406 * memory blocks is retained by the caller, which must guarantee that they
407 * remain valid until the handler is called.
408 *
409 * @param flags Flags specifying how the send call is to be made.
410 *
411 * @param handler The handler to be called when the send operation completes.
412 * Copies will be made of the handler as required. The function signature of
413 * the handler must be:
414 * @code void handler(
415 * const boost::system::error_code& error, // Result of operation.
416 * std::size_t bytes_transferred // Number of bytes sent.
417 * ); @endcode
418 * Regardless of whether the asynchronous operation completes immediately or
419 * not, the handler will not be invoked from within this function. On
420 * immediate completion, invocation of the handler will be performed in a
421 * manner equivalent to using boost::asio::post().
422 *
423 * @par Example
424 * To send a single data buffer use the @ref buffer function as follows:
425 * @code
426 * socket.async_send(boost::asio::buffer(data, size), 0, handler);
427 * @endcode
428 * See the @ref buffer documentation for information on sending multiple
429 * buffers in one go, and how to use it with arrays, boost::array or
430 * std::vector.
431 */
432 template <typename ConstBufferSequence,
433 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
434 std::size_t)) WriteHandler
435 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
436 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,
437 void (boost::system::error_code, std::size_t))
438 async_send(const ConstBufferSequence& buffers,
439 socket_base::message_flags flags,
440 BOOST_ASIO_MOVE_ARG(WriteHandler) handler
441 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
442 {
443 return async_initiate<WriteHandler,
444 void (boost::system::error_code, std::size_t)>(
445 initiate_async_send(this), handler, buffers, flags);
446 }
447
448 /// Receive some data on the socket.
449 /**
450 * This function is used to receive data on the sequenced packet socket. The
451 * function call will block until data has been received successfully, or
452 * until an error occurs.
453 *
454 * @param buffers One or more buffers into which the data will be received.
455 *
456 * @param out_flags After the receive call completes, contains flags
457 * associated with the received data. For example, if the
458 * socket_base::message_end_of_record bit is set then the received data marks
459 * the end of a record.
460 *
461 * @returns The number of bytes received.
462 *
463 * @throws boost::system::system_error Thrown on failure. An error code of
464 * boost::asio::error::eof indicates that the connection was closed by the
465 * peer.
466 *
467 * @par Example
468 * To receive into a single data buffer use the @ref buffer function as
469 * follows:
470 * @code
471 * socket.receive(boost::asio::buffer(data, size), out_flags);
472 * @endcode
473 * See the @ref buffer documentation for information on receiving into
474 * multiple buffers in one go, and how to use it with arrays, boost::array or
475 * std::vector.
476 */
477 template <typename MutableBufferSequence>
478 std::size_t receive(const MutableBufferSequence& buffers,
479 socket_base::message_flags& out_flags)
480 {
481 boost::system::error_code ec;
482 std::size_t s = this->impl_.get_service().receive_with_flags(
483 this->impl_.get_implementation(), buffers, 0, out_flags, ec);
484 boost::asio::detail::throw_error(ec, "receive");
485 return s;
486 }
487
488 /// Receive some data on the socket.
489 /**
490 * This function is used to receive data on the sequenced packet socket. The
491 * function call will block until data has been received successfully, or
492 * until an error occurs.
493 *
494 * @param buffers One or more buffers into which the data will be received.
495 *
496 * @param in_flags Flags specifying how the receive call is to be made.
497 *
498 * @param out_flags After the receive call completes, contains flags
499 * associated with the received data. For example, if the
500 * socket_base::message_end_of_record bit is set then the received data marks
501 * the end of a record.
502 *
503 * @returns The number of bytes received.
504 *
505 * @throws boost::system::system_error Thrown on failure. An error code of
506 * boost::asio::error::eof indicates that the connection was closed by the
507 * peer.
508 *
509 * @note The receive operation may not receive all of the requested number of
510 * bytes. Consider using the @ref read function if you need to ensure that the
511 * requested amount of data is read before the blocking operation completes.
512 *
513 * @par Example
514 * To receive into a single data buffer use the @ref buffer function as
515 * follows:
516 * @code
517 * socket.receive(boost::asio::buffer(data, size), 0, out_flags);
518 * @endcode
519 * See the @ref buffer documentation for information on receiving into
520 * multiple buffers in one go, and how to use it with arrays, boost::array or
521 * std::vector.
522 */
523 template <typename MutableBufferSequence>
524 std::size_t receive(const MutableBufferSequence& buffers,
525 socket_base::message_flags in_flags,
526 socket_base::message_flags& out_flags)
527 {
528 boost::system::error_code ec;
529 std::size_t s = this->impl_.get_service().receive_with_flags(
530 this->impl_.get_implementation(), buffers, in_flags, out_flags, ec);
531 boost::asio::detail::throw_error(ec, "receive");
532 return s;
533 }
534
535 /// Receive some data on a connected socket.
536 /**
537 * This function is used to receive data on the sequenced packet socket. The
538 * function call will block until data has been received successfully, or
539 * until an error occurs.
540 *
541 * @param buffers One or more buffers into which the data will be received.
542 *
543 * @param in_flags Flags specifying how the receive call is to be made.
544 *
545 * @param out_flags After the receive call completes, contains flags
546 * associated with the received data. For example, if the
547 * socket_base::message_end_of_record bit is set then the received data marks
548 * the end of a record.
549 *
550 * @param ec Set to indicate what error occurred, if any.
551 *
552 * @returns The number of bytes received. Returns 0 if an error occurred.
553 *
554 * @note The receive operation may not receive all of the requested number of
555 * bytes. Consider using the @ref read function if you need to ensure that the
556 * requested amount of data is read before the blocking operation completes.
557 */
558 template <typename MutableBufferSequence>
559 std::size_t receive(const MutableBufferSequence& buffers,
560 socket_base::message_flags in_flags,
561 socket_base::message_flags& out_flags, boost::system::error_code& ec)
562 {
563 return this->impl_.get_service().receive_with_flags(
564 this->impl_.get_implementation(), buffers, in_flags, out_flags, ec);
565 }
566
567 /// Start an asynchronous receive.
568 /**
569 * This function is used to asynchronously receive data from the sequenced
570 * packet socket. The function call always returns immediately.
571 *
572 * @param buffers One or more buffers into which the data will be received.
573 * Although the buffers object may be copied as necessary, ownership of the
574 * underlying memory blocks is retained by the caller, which must guarantee
575 * that they remain valid until the handler is called.
576 *
577 * @param out_flags Once the asynchronous operation completes, contains flags
578 * associated with the received data. For example, if the
579 * socket_base::message_end_of_record bit is set then the received data marks
580 * the end of a record. The caller must guarantee that the referenced
581 * variable remains valid until the handler is called.
582 *
583 * @param handler The handler to be called when the receive operation
584 * completes. Copies will be made of the handler as required. The function
585 * signature of the handler must be:
586 * @code void handler(
587 * const boost::system::error_code& error, // Result of operation.
588 * std::size_t bytes_transferred // Number of bytes received.
589 * ); @endcode
590 * Regardless of whether the asynchronous operation completes immediately or
591 * not, the handler will not be invoked from within this function. On
592 * immediate completion, invocation of the handler will be performed in a
593 * manner equivalent to using boost::asio::post().
594 *
595 * @par Example
596 * To receive into a single data buffer use the @ref buffer function as
597 * follows:
598 * @code
599 * socket.async_receive(boost::asio::buffer(data, size), out_flags, handler);
600 * @endcode
601 * See the @ref buffer documentation for information on receiving into
602 * multiple buffers in one go, and how to use it with arrays, boost::array or
603 * std::vector.
604 */
605 template <typename MutableBufferSequence,
606 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
607 std::size_t)) ReadHandler
608 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
609 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
610 void (boost::system::error_code, std::size_t))
611 async_receive(const MutableBufferSequence& buffers,
612 socket_base::message_flags& out_flags,
613 BOOST_ASIO_MOVE_ARG(ReadHandler) handler
614 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
615 {
616 return async_initiate<ReadHandler,
617 void (boost::system::error_code, std::size_t)>(
618 initiate_async_receive_with_flags(this), handler,
619 buffers, socket_base::message_flags(0), &out_flags);
620 }
621
622 /// Start an asynchronous receive.
623 /**
624 * This function is used to asynchronously receive data from the sequenced
625 * data socket. The function call always returns immediately.
626 *
627 * @param buffers One or more buffers into which the data will be received.
628 * Although the buffers object may be copied as necessary, ownership of the
629 * underlying memory blocks is retained by the caller, which must guarantee
630 * that they remain valid until the handler is called.
631 *
632 * @param in_flags Flags specifying how the receive call is to be made.
633 *
634 * @param out_flags Once the asynchronous operation completes, contains flags
635 * associated with the received data. For example, if the
636 * socket_base::message_end_of_record bit is set then the received data marks
637 * the end of a record. The caller must guarantee that the referenced
638 * variable remains valid until the handler is called.
639 *
640 * @param handler The handler to be called when the receive operation
641 * completes. Copies will be made of the handler as required. The function
642 * signature of the handler must be:
643 * @code void handler(
644 * const boost::system::error_code& error, // Result of operation.
645 * std::size_t bytes_transferred // Number of bytes received.
646 * ); @endcode
647 * Regardless of whether the asynchronous operation completes immediately or
648 * not, the handler will not be invoked from within this function. On
649 * immediate completion, invocation of the handler will be performed in a
650 * manner equivalent to using boost::asio::post().
651 *
652 * @par Example
653 * To receive into a single data buffer use the @ref buffer function as
654 * follows:
655 * @code
656 * socket.async_receive(
657 * boost::asio::buffer(data, size),
658 * 0, out_flags, handler);
659 * @endcode
660 * See the @ref buffer documentation for information on receiving into
661 * multiple buffers in one go, and how to use it with arrays, boost::array or
662 * std::vector.
663 */
664 template <typename MutableBufferSequence,
665 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
666 std::size_t)) ReadHandler
667 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
668 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,
669 void (boost::system::error_code, std::size_t))
670 async_receive(const MutableBufferSequence& buffers,
671 socket_base::message_flags in_flags,
672 socket_base::message_flags& out_flags,
673 BOOST_ASIO_MOVE_ARG(ReadHandler) handler
674 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
675 {
676 return async_initiate<ReadHandler,
677 void (boost::system::error_code, std::size_t)>(
678 initiate_async_receive_with_flags(this),
679 handler, buffers, in_flags, &out_flags);
680 }
681
682 private:
683 // Disallow copying and assignment.
684 basic_seq_packet_socket(const basic_seq_packet_socket&) BOOST_ASIO_DELETED;
685 basic_seq_packet_socket& operator=(
686 const basic_seq_packet_socket&) BOOST_ASIO_DELETED;
687
688 class initiate_async_send
689 {
690 public:
691 typedef Executor executor_type;
692
693 explicit initiate_async_send(basic_seq_packet_socket* self)
694 : self_(self)
695 {
696 }
697
698 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
699 {
700 return self_->get_executor();
701 }
702
703 template <typename WriteHandler, typename ConstBufferSequence>
704 void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler,
705 const ConstBufferSequence& buffers,
706 socket_base::message_flags flags) const
707 {
708 // If you get an error on the following line it means that your handler
709 // does not meet the documented type requirements for a WriteHandler.
710 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
711
712 detail::non_const_lvalue<WriteHandler> handler2(handler);
713 self_->impl_.get_service().async_send(
714 self_->impl_.get_implementation(), buffers, flags,
715 handler2.value, self_->impl_.get_executor());
716 }
717
718 private:
719 basic_seq_packet_socket* self_;
720 };
721
722 class initiate_async_receive_with_flags
723 {
724 public:
725 typedef Executor executor_type;
726
727 explicit initiate_async_receive_with_flags(basic_seq_packet_socket* self)
728 : self_(self)
729 {
730 }
731
732 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
733 {
734 return self_->get_executor();
735 }
736
737 template <typename ReadHandler, typename MutableBufferSequence>
738 void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler,
739 const MutableBufferSequence& buffers,
740 socket_base::message_flags in_flags,
741 socket_base::message_flags* out_flags) const
742 {
743 // If you get an error on the following line it means that your handler
744 // does not meet the documented type requirements for a ReadHandler.
745 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
746
747 detail::non_const_lvalue<ReadHandler> handler2(handler);
748 self_->impl_.get_service().async_receive_with_flags(
749 self_->impl_.get_implementation(), buffers, in_flags,
750 *out_flags, handler2.value, self_->impl_.get_executor());
751 }
752
753 private:
754 basic_seq_packet_socket* self_;
755 };
756 };
757
758 } // namespace asio
759 } // namespace boost
760
761 #include <boost/asio/detail/pop_options.hpp>
762
763 #endif // BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_HPP