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