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