2 // basic_seq_packet_socket.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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)
11 #ifndef BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_HPP
12 #define BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_HPP
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18 #include <boost/asio/detail/config.hpp>
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>
25 #include <boost/asio/detail/push_options.hpp>
30 #if !defined(BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL)
31 #define BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL
33 // Forward declaration with defaulted arguments.
34 template <typename Protocol, typename Executor = any_io_executor>
35 class basic_seq_packet_socket;
37 #endif // !defined(BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL)
39 /// Provides sequenced packet socket functionality.
41 * The basic_seq_packet_socket class template provides asynchronous and blocking
42 * sequenced packet socket functionality.
45 * @e Distinct @e objects: Safe.@n
46 * @e Shared @e objects: Unsafe.
48 template <typename Protocol, typename Executor>
49 class basic_seq_packet_socket
50 : public basic_socket<Protocol, Executor>
53 /// The type of the executor associated with the object.
54 typedef Executor executor_type;
56 /// Rebinds the socket type to another executor.
57 template <typename Executor1>
58 struct rebind_executor
60 /// The socket type when rebound to the specified executor.
61 typedef basic_seq_packet_socket<Protocol, Executor1> other;
64 /// The native representation of a socket.
65 #if defined(GENERATING_DOCUMENTATION)
66 typedef implementation_defined native_handle_type;
68 typedef typename basic_socket<Protocol,
69 Executor>::native_handle_type native_handle_type;
72 /// The protocol type.
73 typedef Protocol protocol_type;
75 /// The endpoint type.
76 typedef typename Protocol::endpoint endpoint_type;
78 /// Construct a basic_seq_packet_socket without opening it.
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.
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.
87 explicit basic_seq_packet_socket(const executor_type& ex)
88 : basic_socket<Protocol, Executor>(ex)
92 /// Construct a basic_seq_packet_socket without opening it.
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.
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.
102 template <typename ExecutionContext>
103 explicit basic_seq_packet_socket(ExecutionContext& context,
105 is_convertible<ExecutionContext&, execution_context&>::value
107 : basic_socket<Protocol, Executor>(context)
111 /// Construct and open a basic_seq_packet_socket.
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
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.
120 * @param protocol An object specifying protocol parameters to be used.
122 * @throws boost::system::system_error Thrown on failure.
124 basic_seq_packet_socket(const executor_type& ex,
125 const protocol_type& protocol)
126 : basic_socket<Protocol, Executor>(ex, protocol)
130 /// Construct and open a basic_seq_packet_socket.
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
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.
140 * @param protocol An object specifying protocol parameters to be used.
142 * @throws boost::system::system_error Thrown on failure.
144 template <typename ExecutionContext>
145 basic_seq_packet_socket(ExecutionContext& context,
146 const protocol_type& protocol,
148 is_convertible<ExecutionContext&, execution_context&>::value
150 : basic_socket<Protocol, Executor>(context, protocol)
154 /// Construct a basic_seq_packet_socket, opening it and binding it to the
155 /// given local endpoint.
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.
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.
164 * @param endpoint An endpoint on the local machine to which the sequenced
165 * packet socket will be bound.
167 * @throws boost::system::system_error Thrown on failure.
169 basic_seq_packet_socket(const executor_type& ex,
170 const endpoint_type& endpoint)
171 : basic_socket<Protocol, Executor>(ex, endpoint)
175 /// Construct a basic_seq_packet_socket, opening it and binding it to the
176 /// given local endpoint.
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.
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.
186 * @param endpoint An endpoint on the local machine to which the sequenced
187 * packet socket will be bound.
189 * @throws boost::system::system_error Thrown on failure.
191 template <typename ExecutionContext>
192 basic_seq_packet_socket(ExecutionContext& context,
193 const endpoint_type& endpoint,
195 is_convertible<ExecutionContext&, execution_context&>::value
197 : basic_socket<Protocol, Executor>(context, endpoint)
201 /// Construct a basic_seq_packet_socket on an existing native socket.
203 * This constructor creates a sequenced packet socket object to hold an
204 * existing native socket.
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.
209 * @param protocol An object specifying protocol parameters to be used.
211 * @param native_socket The new underlying socket implementation.
213 * @throws boost::system::system_error Thrown on failure.
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)
221 /// Construct a basic_seq_packet_socket on an existing native socket.
223 * This constructor creates a sequenced packet socket object to hold an
224 * existing native socket.
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.
230 * @param protocol An object specifying protocol parameters to be used.
232 * @param native_socket The new underlying socket implementation.
234 * @throws boost::system::system_error Thrown on failure.
236 template <typename ExecutionContext>
237 basic_seq_packet_socket(ExecutionContext& context,
238 const protocol_type& protocol, const native_handle_type& native_socket,
240 is_convertible<ExecutionContext&, execution_context&>::value
242 : basic_socket<Protocol, Executor>(context, protocol, native_socket)
246 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
247 /// Move-construct a basic_seq_packet_socket from another.
249 * This constructor moves a sequenced packet socket from one object to
252 * @param other The other basic_seq_packet_socket object from which the move
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&)
259 basic_seq_packet_socket(basic_seq_packet_socket&& other) BOOST_ASIO_NOEXCEPT
260 : basic_socket<Protocol, Executor>(std::move(other))
264 /// Move-assign a basic_seq_packet_socket from another.
266 * This assignment operator moves a sequenced packet socket from one object to
269 * @param other The other basic_seq_packet_socket object from which the move
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&)
276 basic_seq_packet_socket& operator=(basic_seq_packet_socket&& other)
278 basic_socket<Protocol, Executor>::operator=(std::move(other));
282 /// Move-construct a basic_seq_packet_socket from a socket of another protocol
285 * This constructor moves a sequenced packet socket from one object to
288 * @param other The other basic_seq_packet_socket object from which the move
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&)
295 template <typename Protocol1, typename Executor1>
296 basic_seq_packet_socket(basic_seq_packet_socket<Protocol1, Executor1>&& other,
298 is_convertible<Protocol1, Protocol>::value
299 && is_convertible<Executor1, Executor>::value
301 : basic_socket<Protocol, Executor>(std::move(other))
305 /// Move-assign a basic_seq_packet_socket from a socket of another protocol
308 * This assignment operator moves a sequenced packet socket from one object to
311 * @param other The other basic_seq_packet_socket object from which the move
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&)
318 template <typename Protocol1, typename Executor1>
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)
325 basic_socket<Protocol, Executor>::operator=(std::move(other));
328 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
330 /// Destroys the socket.
332 * This function destroys the socket, cancelling any outstanding asynchronous
333 * operations associated with the socket as if by calling @c cancel.
335 ~basic_seq_packet_socket()
339 /// Send some data on the socket.
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.
345 * @param buffers One or more data buffers to be sent on the socket.
347 * @param flags Flags specifying how the send call is to be made.
349 * @returns The number of bytes sent.
351 * @throws boost::system::system_error Thrown on failure.
354 * To send a single data buffer use the @ref buffer function as follows:
356 * socket.send(boost::asio::buffer(data, size), 0);
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
362 template <typename ConstBufferSequence>
363 std::size_t send(const ConstBufferSequence& buffers,
364 socket_base::message_flags flags)
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");
373 /// Send some data on the socket.
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
379 * @param buffers One or more data buffers to be sent on the socket.
381 * @param flags Flags specifying how the send call is to be made.
383 * @param ec Set to indicate what error occurred, if any.
385 * @returns The number of bytes sent. Returns 0 if an error occurred.
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.
391 template <typename ConstBufferSequence>
392 std::size_t send(const ConstBufferSequence& buffers,
393 socket_base::message_flags flags, boost::system::error_code& ec)
395 return this->impl_.get_service().send(
396 this->impl_.get_implementation(), buffers, flags, ec);
399 /// Start an asynchronous send.
401 * This function is used to asynchronously send data on the sequenced packet
402 * socket. The function call always returns immediately.
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.
409 * @param flags Flags specifying how the send call is to be made.
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.
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().
424 * To send a single data buffer use the @ref buffer function as follows:
426 * socket.async_send(boost::asio::buffer(data, size), 0, handler);
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
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))
443 return async_initiate<WriteHandler,
444 void (boost::system::error_code, std::size_t)>(
445 initiate_async_send(this), handler, buffers, flags);
448 /// Receive some data on the socket.
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.
454 * @param buffers One or more buffers into which the data will be received.
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.
461 * @returns The number of bytes received.
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
468 * To receive into a single data buffer use the @ref buffer function as
471 * socket.receive(boost::asio::buffer(data, size), out_flags);
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
477 template <typename MutableBufferSequence>
478 std::size_t receive(const MutableBufferSequence& buffers,
479 socket_base::message_flags& out_flags)
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");
488 /// Receive some data on the socket.
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.
494 * @param buffers One or more buffers into which the data will be received.
496 * @param in_flags Flags specifying how the receive call is to be made.
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.
503 * @returns The number of bytes received.
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
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.
514 * To receive into a single data buffer use the @ref buffer function as
517 * socket.receive(boost::asio::buffer(data, size), 0, out_flags);
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
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)
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");
535 /// Receive some data on a connected socket.
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.
541 * @param buffers One or more buffers into which the data will be received.
543 * @param in_flags Flags specifying how the receive call is to be made.
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.
550 * @param ec Set to indicate what error occurred, if any.
552 * @returns The number of bytes received. Returns 0 if an error occurred.
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.
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)
563 return this->impl_.get_service().receive_with_flags(
564 this->impl_.get_implementation(), buffers, in_flags, out_flags, ec);
567 /// Start an asynchronous receive.
569 * This function is used to asynchronously receive data from the sequenced
570 * packet socket. The function call always returns immediately.
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.
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.
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.
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().
596 * To receive into a single data buffer use the @ref buffer function as
599 * socket.async_receive(boost::asio::buffer(data, size), out_flags, handler);
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
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))
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);
622 /// Start an asynchronous receive.
624 * This function is used to asynchronously receive data from the sequenced
625 * data socket. The function call always returns immediately.
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.
632 * @param in_flags Flags specifying how the receive call is to be made.
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.
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.
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().
653 * To receive into a single data buffer use the @ref buffer function as
656 * socket.async_receive(
657 * boost::asio::buffer(data, size),
658 * 0, out_flags, handler);
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
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))
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);
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;
688 class initiate_async_send
691 typedef Executor executor_type;
693 explicit initiate_async_send(basic_seq_packet_socket* self)
698 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
700 return self_->get_executor();
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
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;
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());
719 basic_seq_packet_socket* self_;
722 class initiate_async_receive_with_flags
725 typedef Executor executor_type;
727 explicit initiate_async_receive_with_flags(basic_seq_packet_socket* self)
732 executor_type get_executor() const BOOST_ASIO_NOEXCEPT
734 return self_->get_executor();
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
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;
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());
754 basic_seq_packet_socket* self_;
761 #include <boost/asio/detail/pop_options.hpp>
763 #endif // BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_HPP