]> git.sesse.net Git - casparcg/blob - dependencies64/boost/boost/asio/basic_datagram_socket.hpp
Unpacked dependencies64
[casparcg] / dependencies64 / boost / boost / asio / basic_datagram_socket.hpp
1 //
2 // basic_datagram_socket.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2011 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_DATAGRAM_SOCKET_HPP
12 #define BOOST_ASIO_BASIC_DATAGRAM_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/datagram_socket_service.hpp>
22 #include <boost/asio/detail/handler_type_requirements.hpp>
23 #include <boost/asio/detail/throw_error.hpp>
24 #include <boost/asio/error.hpp>
25
26 #include <boost/asio/detail/push_options.hpp>
27
28 namespace boost {
29 namespace asio {
30
31 /// Provides datagram-oriented socket functionality.
32 /**
33  * The basic_datagram_socket class template provides asynchronous and blocking
34  * datagram-oriented socket functionality.
35  *
36  * @par Thread Safety
37  * @e Distinct @e objects: Safe.@n
38  * @e Shared @e objects: Unsafe.
39  */
40 template <typename Protocol,
41     typename DatagramSocketService = datagram_socket_service<Protocol> >
42 class basic_datagram_socket
43   : public basic_socket<Protocol, DatagramSocketService>
44 {
45 public:
46   /// (Deprecated: Use native_handle_type.) The native representation of a
47   /// socket.
48   typedef typename DatagramSocketService::native_handle_type native_type;
49
50   /// The native representation of a socket.
51   typedef typename DatagramSocketService::native_handle_type native_handle_type;
52
53   /// The protocol type.
54   typedef Protocol protocol_type;
55
56   /// The endpoint type.
57   typedef typename Protocol::endpoint endpoint_type;
58
59   /// Construct a basic_datagram_socket without opening it.
60   /**
61    * This constructor creates a datagram socket without opening it. The open()
62    * function must be called before data can be sent or received on the socket.
63    *
64    * @param io_service The io_service object that the datagram socket will use
65    * to dispatch handlers for any asynchronous operations performed on the
66    * socket.
67    */
68   explicit basic_datagram_socket(boost::asio::io_service& io_service)
69     : basic_socket<Protocol, DatagramSocketService>(io_service)
70   {
71   }
72
73   /// Construct and open a basic_datagram_socket.
74   /**
75    * This constructor creates and opens a datagram socket.
76    *
77    * @param io_service The io_service object that the datagram socket will use
78    * to dispatch handlers for any asynchronous operations performed on the
79    * socket.
80    *
81    * @param protocol An object specifying protocol parameters to be used.
82    *
83    * @throws boost::system::system_error Thrown on failure.
84    */
85   basic_datagram_socket(boost::asio::io_service& io_service,
86       const protocol_type& protocol)
87     : basic_socket<Protocol, DatagramSocketService>(io_service, protocol)
88   {
89   }
90
91   /// Construct a basic_datagram_socket, opening it and binding it to the given
92   /// local endpoint.
93   /**
94    * This constructor creates a datagram socket and automatically opens it bound
95    * to the specified endpoint on the local machine. The protocol used is the
96    * protocol associated with the given endpoint.
97    *
98    * @param io_service The io_service object that the datagram socket will use
99    * to dispatch handlers for any asynchronous operations performed on the
100    * socket.
101    *
102    * @param endpoint An endpoint on the local machine to which the datagram
103    * socket will be bound.
104    *
105    * @throws boost::system::system_error Thrown on failure.
106    */
107   basic_datagram_socket(boost::asio::io_service& io_service,
108       const endpoint_type& endpoint)
109     : basic_socket<Protocol, DatagramSocketService>(io_service, endpoint)
110   {
111   }
112
113   /// Construct a basic_datagram_socket on an existing native socket.
114   /**
115    * This constructor creates a datagram socket object to hold an existing
116    * native socket.
117    *
118    * @param io_service The io_service object that the datagram socket will use
119    * to dispatch handlers for any asynchronous operations performed on the
120    * socket.
121    *
122    * @param protocol An object specifying protocol parameters to be used.
123    *
124    * @param native_socket The new underlying socket implementation.
125    *
126    * @throws boost::system::system_error Thrown on failure.
127    */
128   basic_datagram_socket(boost::asio::io_service& io_service,
129       const protocol_type& protocol, const native_handle_type& native_socket)
130     : basic_socket<Protocol, DatagramSocketService>(
131         io_service, protocol, native_socket)
132   {
133   }
134
135 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
136   /// Move-construct a basic_datagram_socket from another.
137   /**
138    * This constructor moves a datagram socket from one object to another.
139    *
140    * @param other The other basic_datagram_socket object from which the move
141    * will occur.
142    *
143    * @note Following the move, the moved-from object is in the same state as if
144    * constructed using the @c basic_datagram_socket(io_service&) constructor.
145    */
146   basic_datagram_socket(basic_datagram_socket&& other)
147     : basic_socket<Protocol, DatagramSocketService>(
148         BOOST_ASIO_MOVE_CAST(basic_datagram_socket)(other))
149   {
150   }
151
152   /// Move-assign a basic_datagram_socket from another.
153   /**
154    * This assignment operator moves a datagram socket from one object to
155    * another.
156    *
157    * @param other The other basic_datagram_socket object from which the move
158    * will occur.
159    *
160    * @note Following the move, the moved-from object is in the same state as if
161    * constructed using the @c basic_datagram_socket(io_service&) constructor.
162    */
163   basic_datagram_socket& operator=(basic_datagram_socket&& other)
164   {
165     basic_socket<Protocol, DatagramSocketService>::operator=(
166         BOOST_ASIO_MOVE_CAST(basic_datagram_socket)(other));
167     return *this;
168   }
169 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
170
171   /// Send some data on a connected socket.
172   /**
173    * This function is used to send data on the datagram socket. The function
174    * call will block until the data has been sent successfully or an error
175    * occurs.
176    *
177    * @param buffers One ore more data buffers to be sent on the socket.
178    *
179    * @returns The number of bytes sent.
180    *
181    * @throws boost::system::system_error Thrown on failure.
182    *
183    * @note The send operation can only be used with a connected socket. Use
184    * the send_to function to send data on an unconnected datagram socket.
185    *
186    * @par Example
187    * To send a single data buffer use the @ref buffer function as follows:
188    * @code socket.send(boost::asio::buffer(data, size)); @endcode
189    * See the @ref buffer documentation for information on sending multiple
190    * buffers in one go, and how to use it with arrays, boost::array or
191    * std::vector.
192    */
193   template <typename ConstBufferSequence>
194   std::size_t send(const ConstBufferSequence& buffers)
195   {
196     boost::system::error_code ec;
197     std::size_t s = this->get_service().send(
198         this->get_implementation(), buffers, 0, ec);
199     boost::asio::detail::throw_error(ec, "send");
200     return s;
201   }
202
203   /// Send some data on a connected socket.
204   /**
205    * This function is used to send data on the datagram socket. The function
206    * call will block until the data has been sent successfully or an error
207    * occurs.
208    *
209    * @param buffers One ore more data buffers to be sent on the socket.
210    *
211    * @param flags Flags specifying how the send call is to be made.
212    *
213    * @returns The number of bytes sent.
214    *
215    * @throws boost::system::system_error Thrown on failure.
216    *
217    * @note The send operation can only be used with a connected socket. Use
218    * the send_to function to send data on an unconnected datagram socket.
219    */
220   template <typename ConstBufferSequence>
221   std::size_t send(const ConstBufferSequence& buffers,
222       socket_base::message_flags flags)
223   {
224     boost::system::error_code ec;
225     std::size_t s = this->get_service().send(
226         this->get_implementation(), buffers, flags, ec);
227     boost::asio::detail::throw_error(ec, "send");
228     return s;
229   }
230
231   /// Send some data on a connected socket.
232   /**
233    * This function is used to send data on the datagram socket. The function
234    * call will block until the data has been sent successfully or an error
235    * occurs.
236    *
237    * @param buffers One or more data buffers to be sent on the socket.
238    *
239    * @param flags Flags specifying how the send call is to be made.
240    *
241    * @param ec Set to indicate what error occurred, if any.
242    *
243    * @returns The number of bytes sent.
244    *
245    * @note The send operation can only be used with a connected socket. Use
246    * the send_to function to send data on an unconnected datagram socket.
247    */
248   template <typename ConstBufferSequence>
249   std::size_t send(const ConstBufferSequence& buffers,
250       socket_base::message_flags flags, boost::system::error_code& ec)
251   {
252     return this->get_service().send(
253         this->get_implementation(), buffers, flags, ec);
254   }
255
256   /// Start an asynchronous send on a connected socket.
257   /**
258    * This function is used to send data on the datagram socket. The function
259    * call will block until the data has been sent successfully or an error
260    * occurs.
261    *
262    * @param buffers One or more data buffers to be sent on the socket. Although
263    * the buffers object may be copied as necessary, ownership of the underlying
264    * memory blocks is retained by the caller, which must guarantee that they
265    * remain valid until the handler is called.
266    *
267    * @param handler The handler to be called when the send operation completes.
268    * Copies will be made of the handler as required. The function signature of
269    * the handler must be:
270    * @code void handler(
271    *   const boost::system::error_code& error, // Result of operation.
272    *   std::size_t bytes_transferred           // Number of bytes sent.
273    * ); @endcode
274    * Regardless of whether the asynchronous operation completes immediately or
275    * not, the handler will not be invoked from within this function. Invocation
276    * of the handler will be performed in a manner equivalent to using
277    * boost::asio::io_service::post().
278    *
279    * @note The async_send operation can only be used with a connected socket.
280    * Use the async_send_to function to send data on an unconnected datagram
281    * socket.
282    *
283    * @par Example
284    * To send a single data buffer use the @ref buffer function as follows:
285    * @code
286    * socket.async_send(boost::asio::buffer(data, size), handler);
287    * @endcode
288    * See the @ref buffer documentation for information on sending multiple
289    * buffers in one go, and how to use it with arrays, boost::array or
290    * std::vector.
291    */
292   template <typename ConstBufferSequence, typename WriteHandler>
293   void async_send(const ConstBufferSequence& buffers,
294       BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
295   {
296     // If you get an error on the following line it means that your handler does
297     // not meet the documented type requirements for a WriteHandler.
298     BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
299
300     this->get_service().async_send(this->get_implementation(),
301         buffers, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
302   }
303
304   /// Start an asynchronous send on a connected socket.
305   /**
306    * This function is used to send data on the datagram socket. The function
307    * call will block until the data has been sent successfully or an error
308    * occurs.
309    *
310    * @param buffers One or more data buffers to be sent on the socket. Although
311    * the buffers object may be copied as necessary, ownership of the underlying
312    * memory blocks is retained by the caller, which must guarantee that they
313    * remain valid until the handler is called.
314    *
315    * @param flags Flags specifying how the send call is to be made.
316    *
317    * @param handler The handler to be called when the send operation completes.
318    * Copies will be made of the handler as required. The function signature of
319    * the handler must be:
320    * @code void handler(
321    *   const boost::system::error_code& error, // Result of operation.
322    *   std::size_t bytes_transferred           // Number of bytes sent.
323    * ); @endcode
324    * Regardless of whether the asynchronous operation completes immediately or
325    * not, the handler will not be invoked from within this function. Invocation
326    * of the handler will be performed in a manner equivalent to using
327    * boost::asio::io_service::post().
328    *
329    * @note The async_send operation can only be used with a connected socket.
330    * Use the async_send_to function to send data on an unconnected datagram
331    * socket.
332    */
333   template <typename ConstBufferSequence, typename WriteHandler>
334   void async_send(const ConstBufferSequence& buffers,
335       socket_base::message_flags flags,
336       BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
337   {
338     // If you get an error on the following line it means that your handler does
339     // not meet the documented type requirements for a WriteHandler.
340     BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
341
342     this->get_service().async_send(this->get_implementation(),
343         buffers, flags, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
344   }
345
346   /// Send a datagram to the specified endpoint.
347   /**
348    * This function is used to send a datagram to the specified remote endpoint.
349    * The function call will block until the data has been sent successfully or
350    * an error occurs.
351    *
352    * @param buffers One or more data buffers to be sent to the remote endpoint.
353    *
354    * @param destination The remote endpoint to which the data will be sent.
355    *
356    * @returns The number of bytes sent.
357    *
358    * @throws boost::system::system_error Thrown on failure.
359    *
360    * @par Example
361    * To send a single data buffer use the @ref buffer function as follows:
362    * @code
363    * boost::asio::ip::udp::endpoint destination(
364    *     boost::asio::ip::address::from_string("1.2.3.4"), 12345);
365    * socket.send_to(boost::asio::buffer(data, size), destination);
366    * @endcode
367    * See the @ref buffer documentation for information on sending multiple
368    * buffers in one go, and how to use it with arrays, boost::array or
369    * std::vector.
370    */
371   template <typename ConstBufferSequence>
372   std::size_t send_to(const ConstBufferSequence& buffers,
373       const endpoint_type& destination)
374   {
375     boost::system::error_code ec;
376     std::size_t s = this->get_service().send_to(
377         this->get_implementation(), buffers, destination, 0, ec);
378     boost::asio::detail::throw_error(ec, "send_to");
379     return s;
380   }
381
382   /// Send a datagram to the specified endpoint.
383   /**
384    * This function is used to send a datagram to the specified remote endpoint.
385    * The function call will block until the data has been sent successfully or
386    * an error occurs.
387    *
388    * @param buffers One or more data buffers to be sent to the remote endpoint.
389    *
390    * @param destination The remote endpoint to which the data will be sent.
391    *
392    * @param flags Flags specifying how the send call is to be made.
393    *
394    * @returns The number of bytes sent.
395    *
396    * @throws boost::system::system_error Thrown on failure.
397    */
398   template <typename ConstBufferSequence>
399   std::size_t send_to(const ConstBufferSequence& buffers,
400       const endpoint_type& destination, socket_base::message_flags flags)
401   {
402     boost::system::error_code ec;
403     std::size_t s = this->get_service().send_to(
404         this->get_implementation(), buffers, destination, flags, ec);
405     boost::asio::detail::throw_error(ec, "send_to");
406     return s;
407   }
408
409   /// Send a datagram to the specified endpoint.
410   /**
411    * This function is used to send a datagram to the specified remote endpoint.
412    * The function call will block until the data has been sent successfully or
413    * an error occurs.
414    *
415    * @param buffers One or more data buffers to be sent to the remote endpoint.
416    *
417    * @param destination The remote endpoint to which the data will be sent.
418    *
419    * @param flags Flags specifying how the send call is to be made.
420    *
421    * @param ec Set to indicate what error occurred, if any.
422    *
423    * @returns The number of bytes sent.
424    */
425   template <typename ConstBufferSequence>
426   std::size_t send_to(const ConstBufferSequence& buffers,
427       const endpoint_type& destination, socket_base::message_flags flags,
428       boost::system::error_code& ec)
429   {
430     return this->get_service().send_to(this->get_implementation(),
431         buffers, destination, flags, ec);
432   }
433
434   /// Start an asynchronous send.
435   /**
436    * This function is used to asynchronously send a datagram to the specified
437    * remote endpoint. The function call always returns immediately.
438    *
439    * @param buffers One or more data buffers to be sent to the remote endpoint.
440    * Although the buffers object may be copied as necessary, ownership of the
441    * underlying memory blocks is retained by the caller, which must guarantee
442    * that they remain valid until the handler is called.
443    *
444    * @param destination The remote endpoint to which the data will be sent.
445    * Copies will be made of the endpoint as required.
446    *
447    * @param handler The handler to be called when the send operation completes.
448    * Copies will be made of the handler as required. The function signature of
449    * the handler must be:
450    * @code void handler(
451    *   const boost::system::error_code& error, // Result of operation.
452    *   std::size_t bytes_transferred           // Number of bytes sent.
453    * ); @endcode
454    * Regardless of whether the asynchronous operation completes immediately or
455    * not, the handler will not be invoked from within this function. Invocation
456    * of the handler will be performed in a manner equivalent to using
457    * boost::asio::io_service::post().
458    *
459    * @par Example
460    * To send a single data buffer use the @ref buffer function as follows:
461    * @code
462    * boost::asio::ip::udp::endpoint destination(
463    *     boost::asio::ip::address::from_string("1.2.3.4"), 12345);
464    * socket.async_send_to(
465    *     boost::asio::buffer(data, size), destination, handler);
466    * @endcode
467    * See the @ref buffer documentation for information on sending multiple
468    * buffers in one go, and how to use it with arrays, boost::array or
469    * std::vector.
470    */
471   template <typename ConstBufferSequence, typename WriteHandler>
472   void async_send_to(const ConstBufferSequence& buffers,
473       const endpoint_type& destination,
474       BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
475   {
476     // If you get an error on the following line it means that your handler does
477     // not meet the documented type requirements for a WriteHandler.
478     BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
479
480     this->get_service().async_send_to(this->get_implementation(), buffers,
481         destination, 0, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
482   }
483
484   /// Start an asynchronous send.
485   /**
486    * This function is used to asynchronously send a datagram to the specified
487    * remote endpoint. The function call always returns immediately.
488    *
489    * @param buffers One or more data buffers to be sent to the remote endpoint.
490    * Although the buffers object may be copied as necessary, ownership of the
491    * underlying memory blocks is retained by the caller, which must guarantee
492    * that they remain valid until the handler is called.
493    *
494    * @param flags Flags specifying how the send call is to be made.
495    *
496    * @param destination The remote endpoint to which the data will be sent.
497    * Copies will be made of the endpoint as required.
498    *
499    * @param handler The handler to be called when the send operation completes.
500    * Copies will be made of the handler as required. The function signature of
501    * the handler must be:
502    * @code void handler(
503    *   const boost::system::error_code& error, // Result of operation.
504    *   std::size_t bytes_transferred           // Number of bytes sent.
505    * ); @endcode
506    * Regardless of whether the asynchronous operation completes immediately or
507    * not, the handler will not be invoked from within this function. Invocation
508    * of the handler will be performed in a manner equivalent to using
509    * boost::asio::io_service::post().
510    */
511   template <typename ConstBufferSequence, typename WriteHandler>
512   void async_send_to(const ConstBufferSequence& buffers,
513       const endpoint_type& destination, socket_base::message_flags flags,
514       BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
515   {
516     // If you get an error on the following line it means that your handler does
517     // not meet the documented type requirements for a WriteHandler.
518     BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check;
519
520     this->get_service().async_send_to(this->get_implementation(), buffers,
521         destination, flags, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
522   }
523
524   /// Receive some data on a connected socket.
525   /**
526    * This function is used to receive data on the datagram socket. The function
527    * call will block until data has been received successfully or an error
528    * occurs.
529    *
530    * @param buffers One or more buffers into which the data will be received.
531    *
532    * @returns The number of bytes received.
533    *
534    * @throws boost::system::system_error Thrown on failure.
535    *
536    * @note The receive operation can only be used with a connected socket. Use
537    * the receive_from function to receive data on an unconnected datagram
538    * socket.
539    *
540    * @par Example
541    * To receive into a single data buffer use the @ref buffer function as
542    * follows:
543    * @code socket.receive(boost::asio::buffer(data, size)); @endcode
544    * See the @ref buffer documentation for information on receiving into
545    * multiple buffers in one go, and how to use it with arrays, boost::array or
546    * std::vector.
547    */
548   template <typename MutableBufferSequence>
549   std::size_t receive(const MutableBufferSequence& buffers)
550   {
551     boost::system::error_code ec;
552     std::size_t s = this->get_service().receive(
553         this->get_implementation(), buffers, 0, ec);
554     boost::asio::detail::throw_error(ec, "receive");
555     return s;
556   }
557
558   /// Receive some data on a connected socket.
559   /**
560    * This function is used to receive data on the datagram socket. The function
561    * call will block until data has been received successfully or an error
562    * occurs.
563    *
564    * @param buffers One or more buffers into which the data will be received.
565    *
566    * @param flags Flags specifying how the receive call is to be made.
567    *
568    * @returns The number of bytes received.
569    *
570    * @throws boost::system::system_error Thrown on failure.
571    *
572    * @note The receive operation can only be used with a connected socket. Use
573    * the receive_from function to receive data on an unconnected datagram
574    * socket.
575    */
576   template <typename MutableBufferSequence>
577   std::size_t receive(const MutableBufferSequence& buffers,
578       socket_base::message_flags flags)
579   {
580     boost::system::error_code ec;
581     std::size_t s = this->get_service().receive(
582         this->get_implementation(), buffers, flags, ec);
583     boost::asio::detail::throw_error(ec, "receive");
584     return s;
585   }
586
587   /// Receive some data on a connected socket.
588   /**
589    * This function is used to receive data on the datagram socket. The function
590    * call will block until data has been received successfully or an error
591    * occurs.
592    *
593    * @param buffers One or more buffers into which the data will be received.
594    *
595    * @param flags Flags specifying how the receive call is to be made.
596    *
597    * @param ec Set to indicate what error occurred, if any.
598    *
599    * @returns The number of bytes received.
600    *
601    * @note The receive operation can only be used with a connected socket. Use
602    * the receive_from function to receive data on an unconnected datagram
603    * socket.
604    */
605   template <typename MutableBufferSequence>
606   std::size_t receive(const MutableBufferSequence& buffers,
607       socket_base::message_flags flags, boost::system::error_code& ec)
608   {
609     return this->get_service().receive(
610         this->get_implementation(), buffers, flags, ec);
611   }
612
613   /// Start an asynchronous receive on a connected socket.
614   /**
615    * This function is used to asynchronously receive data from the datagram
616    * socket. The function call always returns immediately.
617    *
618    * @param buffers One or more buffers into which the data will be received.
619    * Although the buffers object may be copied as necessary, ownership of the
620    * underlying memory blocks is retained by the caller, which must guarantee
621    * that they remain valid until the handler is called.
622    *
623    * @param handler The handler to be called when the receive operation
624    * completes. Copies will be made of the handler as required. The function
625    * signature of the handler must be:
626    * @code void handler(
627    *   const boost::system::error_code& error, // Result of operation.
628    *   std::size_t bytes_transferred           // Number of bytes received.
629    * ); @endcode
630    * Regardless of whether the asynchronous operation completes immediately or
631    * not, the handler will not be invoked from within this function. Invocation
632    * of the handler will be performed in a manner equivalent to using
633    * boost::asio::io_service::post().
634    *
635    * @note The async_receive operation can only be used with a connected socket.
636    * Use the async_receive_from function to receive data on an unconnected
637    * datagram socket.
638    *
639    * @par Example
640    * To receive into a single data buffer use the @ref buffer function as
641    * follows:
642    * @code
643    * socket.async_receive(boost::asio::buffer(data, size), handler);
644    * @endcode
645    * See the @ref buffer documentation for information on receiving into
646    * multiple buffers in one go, and how to use it with arrays, boost::array or
647    * std::vector.
648    */
649   template <typename MutableBufferSequence, typename ReadHandler>
650   void async_receive(const MutableBufferSequence& buffers,
651       BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
652   {
653     // If you get an error on the following line it means that your handler does
654     // not meet the documented type requirements for a ReadHandler.
655     BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
656
657     this->get_service().async_receive(this->get_implementation(),
658         buffers, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
659   }
660
661   /// Start an asynchronous receive on a connected socket.
662   /**
663    * This function is used to asynchronously receive data from the datagram
664    * socket. The function call always returns immediately.
665    *
666    * @param buffers One or more buffers into which the data will be received.
667    * Although the buffers object may be copied as necessary, ownership of the
668    * underlying memory blocks is retained by the caller, which must guarantee
669    * that they remain valid until the handler is called.
670    *
671    * @param flags Flags specifying how the receive call is to be made.
672    *
673    * @param handler The handler to be called when the receive operation
674    * completes. Copies will be made of the handler as required. The function
675    * signature of the handler must be:
676    * @code void handler(
677    *   const boost::system::error_code& error, // Result of operation.
678    *   std::size_t bytes_transferred           // Number of bytes received.
679    * ); @endcode
680    * Regardless of whether the asynchronous operation completes immediately or
681    * not, the handler will not be invoked from within this function. Invocation
682    * of the handler will be performed in a manner equivalent to using
683    * boost::asio::io_service::post().
684    *
685    * @note The async_receive operation can only be used with a connected socket.
686    * Use the async_receive_from function to receive data on an unconnected
687    * datagram socket.
688    */
689   template <typename MutableBufferSequence, typename ReadHandler>
690   void async_receive(const MutableBufferSequence& buffers,
691       socket_base::message_flags flags,
692       BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
693   {
694     // If you get an error on the following line it means that your handler does
695     // not meet the documented type requirements for a ReadHandler.
696     BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
697
698     this->get_service().async_receive(this->get_implementation(),
699         buffers, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
700   }
701
702   /// Receive a datagram with the endpoint of the sender.
703   /**
704    * This function is used to receive a datagram. The function call will block
705    * until data has been received successfully or an error occurs.
706    *
707    * @param buffers One or more buffers into which the data will be received.
708    *
709    * @param sender_endpoint An endpoint object that receives the endpoint of
710    * the remote sender of the datagram.
711    *
712    * @returns The number of bytes received.
713    *
714    * @throws boost::system::system_error Thrown on failure.
715    *
716    * @par Example
717    * To receive into a single data buffer use the @ref buffer function as
718    * follows:
719    * @code
720    * boost::asio::ip::udp::endpoint sender_endpoint;
721    * socket.receive_from(
722    *     boost::asio::buffer(data, size), sender_endpoint);
723    * @endcode
724    * See the @ref buffer documentation for information on receiving into
725    * multiple buffers in one go, and how to use it with arrays, boost::array or
726    * std::vector.
727    */
728   template <typename MutableBufferSequence>
729   std::size_t receive_from(const MutableBufferSequence& buffers,
730       endpoint_type& sender_endpoint)
731   {
732     boost::system::error_code ec;
733     std::size_t s = this->get_service().receive_from(
734         this->get_implementation(), buffers, sender_endpoint, 0, ec);
735     boost::asio::detail::throw_error(ec, "receive_from");
736     return s;
737   }
738   
739   /// Receive a datagram with the endpoint of the sender.
740   /**
741    * This function is used to receive a datagram. The function call will block
742    * until data has been received successfully or an error occurs.
743    *
744    * @param buffers One or more buffers into which the data will be received.
745    *
746    * @param sender_endpoint An endpoint object that receives the endpoint of
747    * the remote sender of the datagram.
748    *
749    * @param flags Flags specifying how the receive call is to be made.
750    *
751    * @returns The number of bytes received.
752    *
753    * @throws boost::system::system_error Thrown on failure.
754    */
755   template <typename MutableBufferSequence>
756   std::size_t receive_from(const MutableBufferSequence& buffers,
757       endpoint_type& sender_endpoint, socket_base::message_flags flags)
758   {
759     boost::system::error_code ec;
760     std::size_t s = this->get_service().receive_from(
761         this->get_implementation(), buffers, sender_endpoint, flags, ec);
762     boost::asio::detail::throw_error(ec, "receive_from");
763     return s;
764   }
765   
766   /// Receive a datagram with the endpoint of the sender.
767   /**
768    * This function is used to receive a datagram. The function call will block
769    * until data has been received successfully or an error occurs.
770    *
771    * @param buffers One or more buffers into which the data will be received.
772    *
773    * @param sender_endpoint An endpoint object that receives the endpoint of
774    * the remote sender of the datagram.
775    *
776    * @param flags Flags specifying how the receive call is to be made.
777    *
778    * @param ec Set to indicate what error occurred, if any.
779    *
780    * @returns The number of bytes received.
781    */
782   template <typename MutableBufferSequence>
783   std::size_t receive_from(const MutableBufferSequence& buffers,
784       endpoint_type& sender_endpoint, socket_base::message_flags flags,
785       boost::system::error_code& ec)
786   {
787     return this->get_service().receive_from(this->get_implementation(),
788         buffers, sender_endpoint, flags, ec);
789   }
790
791   /// Start an asynchronous receive.
792   /**
793    * This function is used to asynchronously receive a datagram. The function
794    * call always returns immediately.
795    *
796    * @param buffers One or more buffers into which the data will be received.
797    * Although the buffers object may be copied as necessary, ownership of the
798    * underlying memory blocks is retained by the caller, which must guarantee
799    * that they remain valid until the handler is called.
800    *
801    * @param sender_endpoint An endpoint object that receives the endpoint of
802    * the remote sender of the datagram. Ownership of the sender_endpoint object
803    * is retained by the caller, which must guarantee that it is valid until the
804    * handler is called.
805    *
806    * @param handler The handler to be called when the receive operation
807    * completes. Copies will be made of the handler as required. The function
808    * signature of the handler must be:
809    * @code void handler(
810    *   const boost::system::error_code& error, // Result of operation.
811    *   std::size_t bytes_transferred           // Number of bytes received.
812    * ); @endcode
813    * Regardless of whether the asynchronous operation completes immediately or
814    * not, the handler will not be invoked from within this function. Invocation
815    * of the handler will be performed in a manner equivalent to using
816    * boost::asio::io_service::post().
817    *
818    * @par Example
819    * To receive into a single data buffer use the @ref buffer function as
820    * follows:
821    * @code socket.async_receive_from(
822    *     boost::asio::buffer(data, size), 0, sender_endpoint, handler); @endcode
823    * See the @ref buffer documentation for information on receiving into
824    * multiple buffers in one go, and how to use it with arrays, boost::array or
825    * std::vector.
826    */
827   template <typename MutableBufferSequence, typename ReadHandler>
828   void async_receive_from(const MutableBufferSequence& buffers,
829       endpoint_type& sender_endpoint,
830       BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
831   {
832     // If you get an error on the following line it means that your handler does
833     // not meet the documented type requirements for a ReadHandler.
834     BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
835
836     this->get_service().async_receive_from(this->get_implementation(), buffers,
837         sender_endpoint, 0, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
838   }
839
840   /// Start an asynchronous receive.
841   /**
842    * This function is used to asynchronously receive a datagram. The function
843    * call always returns immediately.
844    *
845    * @param buffers One or more buffers into which the data will be received.
846    * Although the buffers object may be copied as necessary, ownership of the
847    * underlying memory blocks is retained by the caller, which must guarantee
848    * that they remain valid until the handler is called.
849    *
850    * @param sender_endpoint An endpoint object that receives the endpoint of
851    * the remote sender of the datagram. Ownership of the sender_endpoint object
852    * is retained by the caller, which must guarantee that it is valid until the
853    * handler is called.
854    *
855    * @param flags Flags specifying how the receive call is to be made.
856    *
857    * @param handler The handler to be called when the receive operation
858    * completes. Copies will be made of the handler as required. The function
859    * signature of the handler must be:
860    * @code void handler(
861    *   const boost::system::error_code& error, // Result of operation.
862    *   std::size_t bytes_transferred           // Number of bytes received.
863    * ); @endcode
864    * Regardless of whether the asynchronous operation completes immediately or
865    * not, the handler will not be invoked from within this function. Invocation
866    * of the handler will be performed in a manner equivalent to using
867    * boost::asio::io_service::post().
868    */
869   template <typename MutableBufferSequence, typename ReadHandler>
870   void async_receive_from(const MutableBufferSequence& buffers,
871       endpoint_type& sender_endpoint, socket_base::message_flags flags,
872       BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
873   {
874     // If you get an error on the following line it means that your handler does
875     // not meet the documented type requirements for a ReadHandler.
876     BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
877
878     this->get_service().async_receive_from(this->get_implementation(), buffers,
879         sender_endpoint, flags, BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
880   }
881 };
882
883 } // namespace asio
884 } // namespace boost
885
886 #include <boost/asio/detail/pop_options.hpp>
887
888 #endif // BOOST_ASIO_BASIC_DATAGRAM_SOCKET_HPP