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

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