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