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