PageRenderTime 75ms CodeModel.GetById 32ms app.highlight 36ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/asio/basic_datagram_socket.hpp

http://hadesmem.googlecode.com/
C++ Header | 888 lines | 241 code | 46 blank | 601 comment | 2 complexity | 83775706ce1a157fa3e4bce93a9bbce5 MD5 | raw file
  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
 28namespace boost {
 29namespace 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 */
 40template <typename Protocol,
 41    typename DatagramSocketService = datagram_socket_service<Protocol> >
 42class basic_datagram_socket
 43  : public basic_socket<Protocol, DatagramSocketService>
 44{
 45public:
 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