2
// basic_datagram_socket.hpp
3
// ~~~~~~~~~~~~~~~~~~~~~~~~~
5
// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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)
11
#ifndef ASIO_BASIC_DATAGRAM_SOCKET_HPP
12
#define ASIO_BASIC_DATAGRAM_SOCKET_HPP
14
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
16
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18
#include "asio/detail/push_options.hpp"
20
#include "asio/detail/push_options.hpp"
22
#include <boost/config.hpp>
23
#include "asio/detail/pop_options.hpp"
25
#include "asio/basic_socket.hpp"
26
#include "asio/datagram_socket_service.hpp"
27
#include "asio/error.hpp"
28
#include "asio/detail/throw_error.hpp"
32
/// Provides datagram-oriented socket functionality.
34
* The basic_datagram_socket class template provides asynchronous and blocking
35
* datagram-oriented socket functionality.
38
* @e Distinct @e objects: Safe.@n
39
* @e Shared @e objects: Unsafe.
41
template <typename Protocol,
42
typename DatagramSocketService = datagram_socket_service<Protocol> >
43
class basic_datagram_socket
44
: public basic_socket<Protocol, DatagramSocketService>
47
/// The native representation of a socket.
48
typedef typename DatagramSocketService::native_type native_type;
50
/// The protocol type.
51
typedef Protocol protocol_type;
53
/// The endpoint type.
54
typedef typename Protocol::endpoint endpoint_type;
56
/// Construct a basic_datagram_socket without opening it.
58
* This constructor creates a datagram socket without opening it. The open()
59
* function must be called before data can be sent or received on the socket.
61
* @param io_service The io_service object that the datagram socket will use
62
* to dispatch handlers for any asynchronous operations performed on the
65
explicit basic_datagram_socket(asio::io_service& io_service)
66
: basic_socket<Protocol, DatagramSocketService>(io_service)
70
/// Construct and open a basic_datagram_socket.
72
* This constructor creates and opens a datagram socket.
74
* @param io_service The io_service object that the datagram socket will use
75
* to dispatch handlers for any asynchronous operations performed on the
78
* @param protocol An object specifying protocol parameters to be used.
80
* @throws asio::system_error Thrown on failure.
82
basic_datagram_socket(asio::io_service& io_service,
83
const protocol_type& protocol)
84
: basic_socket<Protocol, DatagramSocketService>(io_service, protocol)
88
/// Construct a basic_datagram_socket, opening it and binding it to the given
91
* This constructor creates a datagram socket and automatically opens it bound
92
* to the specified endpoint on the local machine. The protocol used is the
93
* protocol associated with the given endpoint.
95
* @param io_service The io_service object that the datagram socket will use
96
* to dispatch handlers for any asynchronous operations performed on the
99
* @param endpoint An endpoint on the local machine to which the datagram
100
* socket will be bound.
102
* @throws asio::system_error Thrown on failure.
104
basic_datagram_socket(asio::io_service& io_service,
105
const endpoint_type& endpoint)
106
: basic_socket<Protocol, DatagramSocketService>(io_service, endpoint)
110
/// Construct a basic_datagram_socket on an existing native socket.
112
* This constructor creates a datagram socket object to hold an existing
115
* @param io_service The io_service object that the datagram socket will use
116
* to dispatch handlers for any asynchronous operations performed on the
119
* @param protocol An object specifying protocol parameters to be used.
121
* @param native_socket The new underlying socket implementation.
123
* @throws asio::system_error Thrown on failure.
125
basic_datagram_socket(asio::io_service& io_service,
126
const protocol_type& protocol, const native_type& native_socket)
127
: basic_socket<Protocol, DatagramSocketService>(
128
io_service, protocol, native_socket)
132
/// Send some data on a connected socket.
134
* This function is used to send data on the datagram socket. The function
135
* call will block until the data has been sent successfully or an error
138
* @param buffers One ore more data buffers to be sent on the socket.
140
* @returns The number of bytes sent.
142
* @throws asio::system_error Thrown on failure.
144
* @note The send operation can only be used with a connected socket. Use
145
* the send_to function to send data on an unconnected datagram socket.
148
* To send a single data buffer use the @ref buffer function as follows:
149
* @code socket.send(asio::buffer(data, size)); @endcode
150
* See the @ref buffer documentation for information on sending multiple
151
* buffers in one go, and how to use it with arrays, boost::array or
154
template <typename ConstBufferSequence>
155
std::size_t send(const ConstBufferSequence& buffers)
158
std::size_t s = this->service.send(this->implementation, buffers, 0, ec);
159
asio::detail::throw_error(ec);
163
/// Send some data on a connected socket.
165
* This function is used to send data on the datagram socket. The function
166
* call will block until the data has been sent successfully or an error
169
* @param buffers One ore more data buffers to be sent on the socket.
171
* @param flags Flags specifying how the send call is to be made.
173
* @returns The number of bytes sent.
175
* @throws asio::system_error Thrown on failure.
177
* @note The send operation can only be used with a connected socket. Use
178
* the send_to function to send data on an unconnected datagram socket.
180
template <typename ConstBufferSequence>
181
std::size_t send(const ConstBufferSequence& buffers,
182
socket_base::message_flags flags)
185
std::size_t s = this->service.send(
186
this->implementation, buffers, flags, ec);
187
asio::detail::throw_error(ec);
191
/// Send some data on a connected socket.
193
* This function is used to send data on the datagram socket. The function
194
* call will block until the data has been sent successfully or an error
197
* @param buffers One or more data buffers to be sent on the socket.
199
* @param flags Flags specifying how the send call is to be made.
201
* @param ec Set to indicate what error occurred, if any.
203
* @returns The number of bytes sent.
205
* @note The send operation can only be used with a connected socket. Use
206
* the send_to function to send data on an unconnected datagram socket.
208
template <typename ConstBufferSequence>
209
std::size_t send(const ConstBufferSequence& buffers,
210
socket_base::message_flags flags, asio::error_code& ec)
212
return this->service.send(this->implementation, buffers, flags, ec);
215
/// Start an asynchronous send on a connected socket.
217
* This function is used to send data on the datagram socket. The function
218
* call will block until the data has been sent successfully or an error
221
* @param buffers One or more data buffers to be sent on the socket. Although
222
* the buffers object may be copied as necessary, ownership of the underlying
223
* memory blocks is retained by the caller, which must guarantee that they
224
* remain valid until the handler is called.
226
* @param handler The handler to be called when the send operation completes.
227
* Copies will be made of the handler as required. The function signature of
228
* the handler must be:
229
* @code void handler(
230
* const asio::error_code& error, // Result of operation.
231
* std::size_t bytes_transferred // Number of bytes sent.
233
* Regardless of whether the asynchronous operation completes immediately or
234
* not, the handler will not be invoked from within this function. Invocation
235
* of the handler will be performed in a manner equivalent to using
236
* asio::io_service::post().
238
* @note The async_send operation can only be used with a connected socket.
239
* Use the async_send_to function to send data on an unconnected datagram
243
* To send a single data buffer use the @ref buffer function as follows:
245
* socket.async_send(asio::buffer(data, size), handler);
247
* See the @ref buffer documentation for information on sending multiple
248
* buffers in one go, and how to use it with arrays, boost::array or
251
template <typename ConstBufferSequence, typename WriteHandler>
252
void async_send(const ConstBufferSequence& buffers, WriteHandler handler)
254
this->service.async_send(this->implementation, buffers, 0, handler);
257
/// Start an asynchronous send on a connected socket.
259
* This function is used to send data on the datagram socket. The function
260
* call will block until the data has been sent successfully or an error
263
* @param buffers One or more data buffers to be sent on the socket. Although
264
* the buffers object may be copied as necessary, ownership of the underlying
265
* memory blocks is retained by the caller, which must guarantee that they
266
* remain valid until the handler is called.
268
* @param flags Flags specifying how the send call is to be made.
270
* @param handler The handler to be called when the send operation completes.
271
* Copies will be made of the handler as required. The function signature of
272
* the handler must be:
273
* @code void handler(
274
* const asio::error_code& error, // Result of operation.
275
* std::size_t bytes_transferred // Number of bytes sent.
277
* Regardless of whether the asynchronous operation completes immediately or
278
* not, the handler will not be invoked from within this function. Invocation
279
* of the handler will be performed in a manner equivalent to using
280
* asio::io_service::post().
282
* @note The async_send operation can only be used with a connected socket.
283
* Use the async_send_to function to send data on an unconnected datagram
286
template <typename ConstBufferSequence, typename WriteHandler>
287
void async_send(const ConstBufferSequence& buffers,
288
socket_base::message_flags flags, WriteHandler handler)
290
this->service.async_send(this->implementation, buffers, flags, handler);
293
/// Send a datagram to the specified endpoint.
295
* This function is used to send a datagram to the specified remote endpoint.
296
* The function call will block until the data has been sent successfully or
299
* @param buffers One or more data buffers to be sent to the remote endpoint.
301
* @param destination The remote endpoint to which the data will be sent.
303
* @returns The number of bytes sent.
305
* @throws asio::system_error Thrown on failure.
308
* To send a single data buffer use the @ref buffer function as follows:
310
* asio::ip::udp::endpoint destination(
311
* asio::ip::address::from_string("1.2.3.4"), 12345);
312
* socket.send_to(asio::buffer(data, size), destination);
314
* See the @ref buffer documentation for information on sending multiple
315
* buffers in one go, and how to use it with arrays, boost::array or
318
template <typename ConstBufferSequence>
319
std::size_t send_to(const ConstBufferSequence& buffers,
320
const endpoint_type& destination)
323
std::size_t s = this->service.send_to(
324
this->implementation, buffers, destination, 0, ec);
325
asio::detail::throw_error(ec);
329
/// Send a datagram to the specified endpoint.
331
* This function is used to send a datagram to the specified remote endpoint.
332
* The function call will block until the data has been sent successfully or
335
* @param buffers One or more data buffers to be sent to the remote endpoint.
337
* @param destination The remote endpoint to which the data will be sent.
339
* @param flags Flags specifying how the send call is to be made.
341
* @returns The number of bytes sent.
343
* @throws asio::system_error Thrown on failure.
345
template <typename ConstBufferSequence>
346
std::size_t send_to(const ConstBufferSequence& buffers,
347
const endpoint_type& destination, socket_base::message_flags flags)
350
std::size_t s = this->service.send_to(
351
this->implementation, buffers, destination, flags, ec);
352
asio::detail::throw_error(ec);
356
/// Send a datagram to the specified endpoint.
358
* This function is used to send a datagram to the specified remote endpoint.
359
* The function call will block until the data has been sent successfully or
362
* @param buffers One or more data buffers to be sent to the remote endpoint.
364
* @param destination The remote endpoint to which the data will be sent.
366
* @param flags Flags specifying how the send call is to be made.
368
* @param ec Set to indicate what error occurred, if any.
370
* @returns The number of bytes sent.
372
template <typename ConstBufferSequence>
373
std::size_t send_to(const ConstBufferSequence& buffers,
374
const endpoint_type& destination, socket_base::message_flags flags,
375
asio::error_code& ec)
377
return this->service.send_to(this->implementation,
378
buffers, destination, flags, ec);
381
/// Start an asynchronous send.
383
* This function is used to asynchronously send a datagram to the specified
384
* remote endpoint. The function call always returns immediately.
386
* @param buffers One or more data buffers to be sent to the remote endpoint.
387
* Although the buffers object may be copied as necessary, ownership of the
388
* underlying memory blocks is retained by the caller, which must guarantee
389
* that they remain valid until the handler is called.
391
* @param destination The remote endpoint to which the data will be sent.
392
* Copies will be made of the endpoint as required.
394
* @param handler The handler to be called when the send operation completes.
395
* Copies will be made of the handler as required. The function signature of
396
* the handler must be:
397
* @code void handler(
398
* const asio::error_code& error, // Result of operation.
399
* std::size_t bytes_transferred // Number of bytes sent.
401
* Regardless of whether the asynchronous operation completes immediately or
402
* not, the handler will not be invoked from within this function. Invocation
403
* of the handler will be performed in a manner equivalent to using
404
* asio::io_service::post().
407
* To send a single data buffer use the @ref buffer function as follows:
409
* asio::ip::udp::endpoint destination(
410
* asio::ip::address::from_string("1.2.3.4"), 12345);
411
* socket.async_send_to(
412
* asio::buffer(data, size), destination, handler);
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
418
template <typename ConstBufferSequence, typename WriteHandler>
419
void async_send_to(const ConstBufferSequence& buffers,
420
const endpoint_type& destination, WriteHandler handler)
422
this->service.async_send_to(this->implementation, buffers, destination, 0,
426
/// Start an asynchronous send.
428
* This function is used to asynchronously send a datagram to the specified
429
* remote endpoint. The function call always returns immediately.
431
* @param buffers One or more data buffers to be sent to the remote endpoint.
432
* Although the buffers object may be copied as necessary, ownership of the
433
* underlying memory blocks is retained by the caller, which must guarantee
434
* that they remain valid until the handler is called.
436
* @param flags Flags specifying how the send call is to be made.
438
* @param destination The remote endpoint to which the data will be sent.
439
* Copies will be made of the endpoint as required.
441
* @param handler The handler to be called when the send operation completes.
442
* Copies will be made of the handler as required. The function signature of
443
* the handler must be:
444
* @code void handler(
445
* const asio::error_code& error, // Result of operation.
446
* std::size_t bytes_transferred // Number of bytes sent.
448
* Regardless of whether the asynchronous operation completes immediately or
449
* not, the handler will not be invoked from within this function. Invocation
450
* of the handler will be performed in a manner equivalent to using
451
* asio::io_service::post().
453
template <typename ConstBufferSequence, typename WriteHandler>
454
void async_send_to(const ConstBufferSequence& buffers,
455
const endpoint_type& destination, socket_base::message_flags flags,
456
WriteHandler handler)
458
this->service.async_send_to(this->implementation, buffers, destination,
462
/// Receive some data on a connected socket.
464
* This function is used to receive data on the datagram socket. The function
465
* call will block until data has been received successfully or an error
468
* @param buffers One or more buffers into which the data will be received.
470
* @returns The number of bytes received.
472
* @throws asio::system_error Thrown on failure.
474
* @note The receive operation can only be used with a connected socket. Use
475
* the receive_from function to receive data on an unconnected datagram
479
* To receive into a single data buffer use the @ref buffer function as
481
* @code socket.receive(asio::buffer(data, size)); @endcode
482
* See the @ref buffer documentation for information on receiving into
483
* multiple buffers in one go, and how to use it with arrays, boost::array or
486
template <typename MutableBufferSequence>
487
std::size_t receive(const MutableBufferSequence& buffers)
490
std::size_t s = this->service.receive(
491
this->implementation, buffers, 0, ec);
492
asio::detail::throw_error(ec);
496
/// Receive some data on a connected socket.
498
* This function is used to receive data on the datagram socket. The function
499
* call will block until data has been received successfully or an error
502
* @param buffers One or more buffers into which the data will be received.
504
* @param flags Flags specifying how the receive call is to be made.
506
* @returns The number of bytes received.
508
* @throws asio::system_error Thrown on failure.
510
* @note The receive operation can only be used with a connected socket. Use
511
* the receive_from function to receive data on an unconnected datagram
514
template <typename MutableBufferSequence>
515
std::size_t receive(const MutableBufferSequence& buffers,
516
socket_base::message_flags flags)
519
std::size_t s = this->service.receive(
520
this->implementation, buffers, flags, ec);
521
asio::detail::throw_error(ec);
525
/// Receive some data on a connected socket.
527
* This function is used to receive data on the datagram socket. The function
528
* call will block until data has been received successfully or an error
531
* @param buffers One or more buffers into which the data will be received.
533
* @param flags Flags specifying how the receive call is to be made.
535
* @param ec Set to indicate what error occurred, if any.
537
* @returns The number of bytes received.
539
* @note The receive operation can only be used with a connected socket. Use
540
* the receive_from function to receive data on an unconnected datagram
543
template <typename MutableBufferSequence>
544
std::size_t receive(const MutableBufferSequence& buffers,
545
socket_base::message_flags flags, asio::error_code& ec)
547
return this->service.receive(this->implementation, buffers, flags, ec);
550
/// Start an asynchronous receive on a connected socket.
552
* This function is used to asynchronously receive data from the datagram
553
* socket. The function call always returns immediately.
555
* @param buffers One or more buffers into which the data will be received.
556
* Although the buffers object may be copied as necessary, ownership of the
557
* underlying memory blocks is retained by the caller, which must guarantee
558
* that they remain valid until the handler is called.
560
* @param handler The handler to be called when the receive operation
561
* completes. Copies will be made of the handler as required. The function
562
* signature of the handler must be:
563
* @code void handler(
564
* const asio::error_code& error, // Result of operation.
565
* std::size_t bytes_transferred // Number of bytes received.
567
* Regardless of whether the asynchronous operation completes immediately or
568
* not, the handler will not be invoked from within this function. Invocation
569
* of the handler will be performed in a manner equivalent to using
570
* asio::io_service::post().
572
* @note The async_receive operation can only be used with a connected socket.
573
* Use the async_receive_from function to receive data on an unconnected
577
* To receive into a single data buffer use the @ref buffer function as
580
* socket.async_receive(asio::buffer(data, size), handler);
582
* See the @ref buffer documentation for information on receiving into
583
* multiple buffers in one go, and how to use it with arrays, boost::array or
586
template <typename MutableBufferSequence, typename ReadHandler>
587
void async_receive(const MutableBufferSequence& buffers, ReadHandler handler)
589
this->service.async_receive(this->implementation, buffers, 0, handler);
592
/// Start an asynchronous receive on a connected socket.
594
* This function is used to asynchronously receive data from the datagram
595
* socket. The function call always returns immediately.
597
* @param buffers One or more buffers into which the data will be received.
598
* Although the buffers object may be copied as necessary, ownership of the
599
* underlying memory blocks is retained by the caller, which must guarantee
600
* that they remain valid until the handler is called.
602
* @param flags Flags specifying how the receive call is to be made.
604
* @param handler The handler to be called when the receive operation
605
* completes. Copies will be made of the handler as required. The function
606
* signature of the handler must be:
607
* @code void handler(
608
* const asio::error_code& error, // Result of operation.
609
* std::size_t bytes_transferred // Number of bytes received.
611
* Regardless of whether the asynchronous operation completes immediately or
612
* not, the handler will not be invoked from within this function. Invocation
613
* of the handler will be performed in a manner equivalent to using
614
* asio::io_service::post().
616
* @note The async_receive operation can only be used with a connected socket.
617
* Use the async_receive_from function to receive data on an unconnected
620
template <typename MutableBufferSequence, typename ReadHandler>
621
void async_receive(const MutableBufferSequence& buffers,
622
socket_base::message_flags flags, ReadHandler handler)
624
this->service.async_receive(this->implementation, buffers, flags, handler);
627
/// Receive a datagram with the endpoint of the sender.
629
* This function is used to receive a datagram. The function call will block
630
* until data has been received successfully or an error occurs.
632
* @param buffers One or more buffers into which the data will be received.
634
* @param sender_endpoint An endpoint object that receives the endpoint of
635
* the remote sender of the datagram.
637
* @returns The number of bytes received.
639
* @throws asio::system_error Thrown on failure.
642
* To receive into a single data buffer use the @ref buffer function as
645
* asio::ip::udp::endpoint sender_endpoint;
646
* socket.receive_from(
647
* asio::buffer(data, size), sender_endpoint);
649
* See the @ref buffer documentation for information on receiving into
650
* multiple buffers in one go, and how to use it with arrays, boost::array or
653
template <typename MutableBufferSequence>
654
std::size_t receive_from(const MutableBufferSequence& buffers,
655
endpoint_type& sender_endpoint)
658
std::size_t s = this->service.receive_from(
659
this->implementation, buffers, sender_endpoint, 0, ec);
660
asio::detail::throw_error(ec);
664
/// Receive a datagram with the endpoint of the sender.
666
* This function is used to receive a datagram. The function call will block
667
* until data has been received successfully or an error occurs.
669
* @param buffers One or more buffers into which the data will be received.
671
* @param sender_endpoint An endpoint object that receives the endpoint of
672
* the remote sender of the datagram.
674
* @param flags Flags specifying how the receive call is to be made.
676
* @returns The number of bytes received.
678
* @throws asio::system_error Thrown on failure.
680
template <typename MutableBufferSequence>
681
std::size_t receive_from(const MutableBufferSequence& buffers,
682
endpoint_type& sender_endpoint, socket_base::message_flags flags)
685
std::size_t s = this->service.receive_from(
686
this->implementation, buffers, sender_endpoint, flags, ec);
687
asio::detail::throw_error(ec);
691
/// Receive a datagram with the endpoint of the sender.
693
* This function is used to receive a datagram. The function call will block
694
* until data has been received successfully or an error occurs.
696
* @param buffers One or more buffers into which the data will be received.
698
* @param sender_endpoint An endpoint object that receives the endpoint of
699
* the remote sender of the datagram.
701
* @param flags Flags specifying how the receive call is to be made.
703
* @param ec Set to indicate what error occurred, if any.
705
* @returns The number of bytes received.
707
template <typename MutableBufferSequence>
708
std::size_t receive_from(const MutableBufferSequence& buffers,
709
endpoint_type& sender_endpoint, socket_base::message_flags flags,
710
asio::error_code& ec)
712
return this->service.receive_from(this->implementation, buffers,
713
sender_endpoint, flags, ec);
716
/// Start an asynchronous receive.
718
* This function is used to asynchronously receive a datagram. The function
719
* call always returns immediately.
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.
726
* @param sender_endpoint An endpoint object that receives the endpoint of
727
* the remote sender of the datagram. Ownership of the sender_endpoint object
728
* is retained by the caller, which must guarantee that it is valid until the
731
* @param handler The handler to be called when the receive operation
732
* completes. Copies will be made of the handler as required. The function
733
* signature of the handler must be:
734
* @code void handler(
735
* const asio::error_code& error, // Result of operation.
736
* std::size_t bytes_transferred // Number of bytes received.
738
* Regardless of whether the asynchronous operation completes immediately or
739
* not, the handler will not be invoked from within this function. Invocation
740
* of the handler will be performed in a manner equivalent to using
741
* asio::io_service::post().
744
* To receive into a single data buffer use the @ref buffer function as
746
* @code socket.async_receive_from(
747
* asio::buffer(data, size), 0, sender_endpoint, handler); @endcode
748
* See the @ref buffer documentation for information on receiving into
749
* multiple buffers in one go, and how to use it with arrays, boost::array or
752
template <typename MutableBufferSequence, typename ReadHandler>
753
void async_receive_from(const MutableBufferSequence& buffers,
754
endpoint_type& sender_endpoint, ReadHandler handler)
756
this->service.async_receive_from(this->implementation, buffers,
757
sender_endpoint, 0, handler);
760
/// Start an asynchronous receive.
762
* This function is used to asynchronously receive a datagram. The function
763
* call always returns immediately.
765
* @param buffers One or more buffers into which the data will be received.
766
* Although the buffers object may be copied as necessary, ownership of the
767
* underlying memory blocks is retained by the caller, which must guarantee
768
* that they remain valid until the handler is called.
770
* @param sender_endpoint An endpoint object that receives the endpoint of
771
* the remote sender of the datagram. Ownership of the sender_endpoint object
772
* is retained by the caller, which must guarantee that it is valid until the
775
* @param flags Flags specifying how the receive call is to be made.
777
* @param handler The handler to be called when the receive operation
778
* completes. Copies will be made of the handler as required. The function
779
* signature of the handler must be:
780
* @code void handler(
781
* const asio::error_code& error, // Result of operation.
782
* std::size_t bytes_transferred // Number of bytes received.
784
* Regardless of whether the asynchronous operation completes immediately or
785
* not, the handler will not be invoked from within this function. Invocation
786
* of the handler will be performed in a manner equivalent to using
787
* asio::io_service::post().
789
template <typename MutableBufferSequence, typename ReadHandler>
790
void async_receive_from(const MutableBufferSequence& buffers,
791
endpoint_type& sender_endpoint, socket_base::message_flags flags,
794
this->service.async_receive_from(this->implementation, buffers,
795
sender_endpoint, flags, handler);
801
#include "asio/detail/pop_options.hpp"
803
#endif // ASIO_BASIC_DATAGRAM_SOCKET_HPP