]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // |
2 | // basic_seq_packet_socket.hpp | |
3 | // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
4 | // | |
f67539c2 | 5 | // Copyright (c) 2003-2020 Christopher M. Kohlhoff (chris at kohlhoff dot com) |
7c673cae FG |
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_SEQ_PACKET_SOCKET_HPP | |
12 | #define BOOST_ASIO_BASIC_SEQ_PACKET_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/throw_error.hpp> | |
23 | #include <boost/asio/error.hpp> | |
b32b8144 | 24 | |
7c673cae FG |
25 | #include <boost/asio/detail/push_options.hpp> |
26 | ||
27 | namespace boost { | |
28 | namespace asio { | |
29 | ||
92f5a8d4 TL |
30 | #if !defined(BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL) |
31 | #define BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL | |
32 | ||
33 | // Forward declaration with defaulted arguments. | |
20effc67 | 34 | template <typename Protocol, typename Executor = any_io_executor> |
92f5a8d4 TL |
35 | class basic_seq_packet_socket; |
36 | ||
37 | #endif // !defined(BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL) | |
38 | ||
7c673cae FG |
39 | /// Provides sequenced packet socket functionality. |
40 | /** | |
41 | * The basic_seq_packet_socket class template provides asynchronous and blocking | |
42 | * sequenced packet socket functionality. | |
43 | * | |
44 | * @par Thread Safety | |
45 | * @e Distinct @e objects: Safe.@n | |
46 | * @e Shared @e objects: Unsafe. | |
47 | */ | |
92f5a8d4 | 48 | template <typename Protocol, typename Executor> |
7c673cae | 49 | class basic_seq_packet_socket |
92f5a8d4 | 50 | : public basic_socket<Protocol, Executor> |
7c673cae FG |
51 | { |
52 | public: | |
92f5a8d4 TL |
53 | /// The type of the executor associated with the object. |
54 | typedef Executor executor_type; | |
55 | ||
56 | /// Rebinds the socket type to another executor. | |
57 | template <typename Executor1> | |
58 | struct rebind_executor | |
59 | { | |
60 | /// The socket type when rebound to the specified executor. | |
61 | typedef basic_seq_packet_socket<Protocol, Executor1> other; | |
62 | }; | |
63 | ||
7c673cae | 64 | /// The native representation of a socket. |
b32b8144 FG |
65 | #if defined(GENERATING_DOCUMENTATION) |
66 | typedef implementation_defined native_handle_type; | |
67 | #else | |
92f5a8d4 TL |
68 | typedef typename basic_socket<Protocol, |
69 | Executor>::native_handle_type native_handle_type; | |
b32b8144 | 70 | #endif |
7c673cae FG |
71 | |
72 | /// The protocol type. | |
73 | typedef Protocol protocol_type; | |
74 | ||
75 | /// The endpoint type. | |
76 | typedef typename Protocol::endpoint endpoint_type; | |
77 | ||
78 | /// Construct a basic_seq_packet_socket without opening it. | |
79 | /** | |
80 | * This constructor creates a sequenced packet socket without opening it. The | |
81 | * socket needs to be opened and then connected or accepted before data can | |
82 | * be sent or received on it. | |
83 | * | |
92f5a8d4 TL |
84 | * @param ex The I/O executor that the socket will use, by default, to |
85 | * dispatch handlers for any asynchronous operations performed on the socket. | |
86 | */ | |
87 | explicit basic_seq_packet_socket(const executor_type& ex) | |
88 | : basic_socket<Protocol, Executor>(ex) | |
89 | { | |
90 | } | |
91 | ||
92 | /// Construct a basic_seq_packet_socket without opening it. | |
93 | /** | |
94 | * This constructor creates a sequenced packet socket without opening it. The | |
95 | * socket needs to be opened and then connected or accepted before data can | |
96 | * be sent or received on it. | |
97 | * | |
98 | * @param context An execution context which provides the I/O executor that | |
99 | * the socket will use, by default, to dispatch handlers for any asynchronous | |
100 | * operations performed on the socket. | |
7c673cae | 101 | */ |
92f5a8d4 TL |
102 | template <typename ExecutionContext> |
103 | explicit basic_seq_packet_socket(ExecutionContext& context, | |
104 | typename enable_if< | |
105 | is_convertible<ExecutionContext&, execution_context&>::value | |
106 | >::type* = 0) | |
107 | : basic_socket<Protocol, Executor>(context) | |
7c673cae FG |
108 | { |
109 | } | |
110 | ||
111 | /// Construct and open a basic_seq_packet_socket. | |
112 | /** | |
113 | * This constructor creates and opens a sequenced_packet socket. The socket | |
114 | * needs to be connected or accepted before data can be sent or received on | |
115 | * it. | |
116 | * | |
92f5a8d4 TL |
117 | * @param ex The I/O executor that the socket will use, by default, to |
118 | * dispatch handlers for any asynchronous operations performed on the socket. | |
7c673cae FG |
119 | * |
120 | * @param protocol An object specifying protocol parameters to be used. | |
121 | * | |
122 | * @throws boost::system::system_error Thrown on failure. | |
123 | */ | |
92f5a8d4 | 124 | basic_seq_packet_socket(const executor_type& ex, |
7c673cae | 125 | const protocol_type& protocol) |
92f5a8d4 TL |
126 | : basic_socket<Protocol, Executor>(ex, protocol) |
127 | { | |
128 | } | |
129 | ||
130 | /// Construct and open a basic_seq_packet_socket. | |
131 | /** | |
132 | * This constructor creates and opens a sequenced_packet socket. The socket | |
133 | * needs to be connected or accepted before data can be sent or received on | |
134 | * it. | |
135 | * | |
136 | * @param context An execution context which provides the I/O executor that | |
137 | * the socket will use, by default, to dispatch handlers for any asynchronous | |
138 | * operations performed on the socket. | |
139 | * | |
140 | * @param protocol An object specifying protocol parameters to be used. | |
141 | * | |
142 | * @throws boost::system::system_error Thrown on failure. | |
143 | */ | |
144 | template <typename ExecutionContext> | |
145 | basic_seq_packet_socket(ExecutionContext& context, | |
146 | const protocol_type& protocol, | |
147 | typename enable_if< | |
148 | is_convertible<ExecutionContext&, execution_context&>::value | |
149 | >::type* = 0) | |
150 | : basic_socket<Protocol, Executor>(context, protocol) | |
7c673cae FG |
151 | { |
152 | } | |
153 | ||
154 | /// Construct a basic_seq_packet_socket, opening it and binding it to the | |
155 | /// given local endpoint. | |
156 | /** | |
157 | * This constructor creates a sequenced packet socket and automatically opens | |
158 | * it bound to the specified endpoint on the local machine. The protocol used | |
159 | * is the protocol associated with the given endpoint. | |
160 | * | |
92f5a8d4 TL |
161 | * @param ex The I/O executor that the socket will use, by default, to |
162 | * dispatch handlers for any asynchronous operations performed on the socket. | |
7c673cae FG |
163 | * |
164 | * @param endpoint An endpoint on the local machine to which the sequenced | |
165 | * packet socket will be bound. | |
166 | * | |
167 | * @throws boost::system::system_error Thrown on failure. | |
168 | */ | |
92f5a8d4 | 169 | basic_seq_packet_socket(const executor_type& ex, |
7c673cae | 170 | const endpoint_type& endpoint) |
92f5a8d4 TL |
171 | : basic_socket<Protocol, Executor>(ex, endpoint) |
172 | { | |
173 | } | |
174 | ||
175 | /// Construct a basic_seq_packet_socket, opening it and binding it to the | |
176 | /// given local endpoint. | |
177 | /** | |
178 | * This constructor creates a sequenced packet socket and automatically opens | |
179 | * it bound to the specified endpoint on the local machine. The protocol used | |
180 | * is the protocol associated with the given endpoint. | |
181 | * | |
182 | * @param context An execution context which provides the I/O executor that | |
183 | * the socket will use, by default, to dispatch handlers for any asynchronous | |
184 | * operations performed on the socket. | |
185 | * | |
186 | * @param endpoint An endpoint on the local machine to which the sequenced | |
187 | * packet socket will be bound. | |
188 | * | |
189 | * @throws boost::system::system_error Thrown on failure. | |
190 | */ | |
191 | template <typename ExecutionContext> | |
192 | basic_seq_packet_socket(ExecutionContext& context, | |
193 | const endpoint_type& endpoint, | |
194 | typename enable_if< | |
195 | is_convertible<ExecutionContext&, execution_context&>::value | |
196 | >::type* = 0) | |
197 | : basic_socket<Protocol, Executor>(context, endpoint) | |
7c673cae FG |
198 | { |
199 | } | |
200 | ||
201 | /// Construct a basic_seq_packet_socket on an existing native socket. | |
202 | /** | |
203 | * This constructor creates a sequenced packet socket object to hold an | |
204 | * existing native socket. | |
205 | * | |
92f5a8d4 TL |
206 | * @param ex The I/O executor that the socket will use, by default, to |
207 | * dispatch handlers for any asynchronous operations performed on the socket. | |
7c673cae FG |
208 | * |
209 | * @param protocol An object specifying protocol parameters to be used. | |
210 | * | |
211 | * @param native_socket The new underlying socket implementation. | |
212 | * | |
213 | * @throws boost::system::system_error Thrown on failure. | |
214 | */ | |
92f5a8d4 | 215 | basic_seq_packet_socket(const executor_type& ex, |
7c673cae | 216 | const protocol_type& protocol, const native_handle_type& native_socket) |
92f5a8d4 TL |
217 | : basic_socket<Protocol, Executor>(ex, protocol, native_socket) |
218 | { | |
219 | } | |
220 | ||
221 | /// Construct a basic_seq_packet_socket on an existing native socket. | |
222 | /** | |
223 | * This constructor creates a sequenced packet socket object to hold an | |
224 | * existing native socket. | |
225 | * | |
226 | * @param context An execution context which provides the I/O executor that | |
227 | * the socket will use, by default, to dispatch handlers for any asynchronous | |
228 | * operations performed on the socket. | |
229 | * | |
230 | * @param protocol An object specifying protocol parameters to be used. | |
231 | * | |
232 | * @param native_socket The new underlying socket implementation. | |
233 | * | |
234 | * @throws boost::system::system_error Thrown on failure. | |
235 | */ | |
236 | template <typename ExecutionContext> | |
237 | basic_seq_packet_socket(ExecutionContext& context, | |
238 | const protocol_type& protocol, const native_handle_type& native_socket, | |
239 | typename enable_if< | |
240 | is_convertible<ExecutionContext&, execution_context&>::value | |
241 | >::type* = 0) | |
242 | : basic_socket<Protocol, Executor>(context, protocol, native_socket) | |
7c673cae FG |
243 | { |
244 | } | |
245 | ||
246 | #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) | |
247 | /// Move-construct a basic_seq_packet_socket from another. | |
248 | /** | |
249 | * This constructor moves a sequenced packet socket from one object to | |
250 | * another. | |
251 | * | |
252 | * @param other The other basic_seq_packet_socket object from which the move | |
253 | * will occur. | |
254 | * | |
255 | * @note Following the move, the moved-from object is in the same state as if | |
92f5a8d4 TL |
256 | * constructed using the @c basic_seq_packet_socket(const executor_type&) |
257 | * constructor. | |
7c673cae | 258 | */ |
92f5a8d4 TL |
259 | basic_seq_packet_socket(basic_seq_packet_socket&& other) BOOST_ASIO_NOEXCEPT |
260 | : basic_socket<Protocol, Executor>(std::move(other)) | |
7c673cae FG |
261 | { |
262 | } | |
263 | ||
264 | /// Move-assign a basic_seq_packet_socket from another. | |
265 | /** | |
266 | * This assignment operator moves a sequenced packet socket from one object to | |
267 | * another. | |
268 | * | |
269 | * @param other The other basic_seq_packet_socket object from which the move | |
270 | * will occur. | |
271 | * | |
272 | * @note Following the move, the moved-from object is in the same state as if | |
92f5a8d4 TL |
273 | * constructed using the @c basic_seq_packet_socket(const executor_type&) |
274 | * constructor. | |
7c673cae FG |
275 | */ |
276 | basic_seq_packet_socket& operator=(basic_seq_packet_socket&& other) | |
277 | { | |
92f5a8d4 | 278 | basic_socket<Protocol, Executor>::operator=(std::move(other)); |
7c673cae FG |
279 | return *this; |
280 | } | |
281 | ||
282 | /// Move-construct a basic_seq_packet_socket from a socket of another protocol | |
283 | /// type. | |
284 | /** | |
285 | * This constructor moves a sequenced packet socket from one object to | |
286 | * another. | |
287 | * | |
288 | * @param other The other basic_seq_packet_socket object from which the move | |
289 | * will occur. | |
290 | * | |
291 | * @note Following the move, the moved-from object is in the same state as if | |
92f5a8d4 TL |
292 | * constructed using the @c basic_seq_packet_socket(const executor_type&) |
293 | * constructor. | |
7c673cae | 294 | */ |
92f5a8d4 TL |
295 | template <typename Protocol1, typename Executor1> |
296 | basic_seq_packet_socket(basic_seq_packet_socket<Protocol1, Executor1>&& other, | |
297 | typename enable_if< | |
298 | is_convertible<Protocol1, Protocol>::value | |
299 | && is_convertible<Executor1, Executor>::value | |
300 | >::type* = 0) | |
301 | : basic_socket<Protocol, Executor>(std::move(other)) | |
7c673cae FG |
302 | { |
303 | } | |
304 | ||
305 | /// Move-assign a basic_seq_packet_socket from a socket of another protocol | |
306 | /// type. | |
307 | /** | |
308 | * This assignment operator moves a sequenced packet socket from one object to | |
309 | * another. | |
310 | * | |
311 | * @param other The other basic_seq_packet_socket object from which the move | |
312 | * will occur. | |
313 | * | |
314 | * @note Following the move, the moved-from object is in the same state as if | |
92f5a8d4 TL |
315 | * constructed using the @c basic_seq_packet_socket(const executor_type&) |
316 | * constructor. | |
7c673cae | 317 | */ |
92f5a8d4 TL |
318 | template <typename Protocol1, typename Executor1> |
319 | typename enable_if< | |
320 | is_convertible<Protocol1, Protocol>::value | |
321 | && is_convertible<Executor1, Executor>::value, | |
322 | basic_seq_packet_socket& | |
323 | >::type operator=(basic_seq_packet_socket<Protocol1, Executor1>&& other) | |
7c673cae | 324 | { |
92f5a8d4 | 325 | basic_socket<Protocol, Executor>::operator=(std::move(other)); |
7c673cae FG |
326 | return *this; |
327 | } | |
328 | #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) | |
329 | ||
b32b8144 FG |
330 | /// Destroys the socket. |
331 | /** | |
332 | * This function destroys the socket, cancelling any outstanding asynchronous | |
333 | * operations associated with the socket as if by calling @c cancel. | |
334 | */ | |
335 | ~basic_seq_packet_socket() | |
336 | { | |
337 | } | |
338 | ||
7c673cae FG |
339 | /// Send some data on the socket. |
340 | /** | |
341 | * This function is used to send data on the sequenced packet socket. The | |
342 | * function call will block until the data has been sent successfully, or an | |
343 | * until error occurs. | |
344 | * | |
345 | * @param buffers One or more data buffers to be sent on the socket. | |
346 | * | |
347 | * @param flags Flags specifying how the send call is to be made. | |
348 | * | |
349 | * @returns The number of bytes sent. | |
350 | * | |
351 | * @throws boost::system::system_error Thrown on failure. | |
352 | * | |
353 | * @par Example | |
354 | * To send a single data buffer use the @ref buffer function as follows: | |
355 | * @code | |
356 | * socket.send(boost::asio::buffer(data, size), 0); | |
357 | * @endcode | |
358 | * See the @ref buffer documentation for information on sending multiple | |
359 | * buffers in one go, and how to use it with arrays, boost::array or | |
360 | * std::vector. | |
361 | */ | |
362 | template <typename ConstBufferSequence> | |
363 | std::size_t send(const ConstBufferSequence& buffers, | |
364 | socket_base::message_flags flags) | |
365 | { | |
366 | boost::system::error_code ec; | |
92f5a8d4 TL |
367 | std::size_t s = this->impl_.get_service().send( |
368 | this->impl_.get_implementation(), buffers, flags, ec); | |
7c673cae FG |
369 | boost::asio::detail::throw_error(ec, "send"); |
370 | return s; | |
371 | } | |
372 | ||
373 | /// Send some data on the socket. | |
374 | /** | |
375 | * This function is used to send data on the sequenced packet socket. The | |
376 | * function call will block the data has been sent successfully, or an until | |
377 | * error occurs. | |
378 | * | |
379 | * @param buffers One or more data buffers to be sent on the socket. | |
380 | * | |
381 | * @param flags Flags specifying how the send call is to be made. | |
382 | * | |
383 | * @param ec Set to indicate what error occurred, if any. | |
384 | * | |
385 | * @returns The number of bytes sent. Returns 0 if an error occurred. | |
386 | * | |
387 | * @note The send operation may not transmit all of the data to the peer. | |
388 | * Consider using the @ref write function if you need to ensure that all data | |
389 | * is written before the blocking operation completes. | |
390 | */ | |
391 | template <typename ConstBufferSequence> | |
392 | std::size_t send(const ConstBufferSequence& buffers, | |
393 | socket_base::message_flags flags, boost::system::error_code& ec) | |
394 | { | |
92f5a8d4 TL |
395 | return this->impl_.get_service().send( |
396 | this->impl_.get_implementation(), buffers, flags, ec); | |
7c673cae FG |
397 | } |
398 | ||
399 | /// Start an asynchronous send. | |
400 | /** | |
401 | * This function is used to asynchronously send data on the sequenced packet | |
402 | * socket. The function call always returns immediately. | |
403 | * | |
404 | * @param buffers One or more data buffers to be sent on the socket. Although | |
405 | * the buffers object may be copied as necessary, ownership of the underlying | |
406 | * memory blocks is retained by the caller, which must guarantee that they | |
407 | * remain valid until the handler is called. | |
408 | * | |
409 | * @param flags Flags specifying how the send call is to be made. | |
410 | * | |
411 | * @param handler The handler to be called when the send operation completes. | |
412 | * Copies will be made of the handler as required. The function signature of | |
413 | * the handler must be: | |
414 | * @code void handler( | |
415 | * const boost::system::error_code& error, // Result of operation. | |
416 | * std::size_t bytes_transferred // Number of bytes sent. | |
417 | * ); @endcode | |
418 | * Regardless of whether the asynchronous operation completes immediately or | |
92f5a8d4 TL |
419 | * not, the handler will not be invoked from within this function. On |
420 | * immediate completion, invocation of the handler will be performed in a | |
421 | * manner equivalent to using boost::asio::post(). | |
7c673cae FG |
422 | * |
423 | * @par Example | |
424 | * To send a single data buffer use the @ref buffer function as follows: | |
425 | * @code | |
426 | * socket.async_send(boost::asio::buffer(data, size), 0, handler); | |
427 | * @endcode | |
428 | * See the @ref buffer documentation for information on sending multiple | |
429 | * buffers in one go, and how to use it with arrays, boost::array or | |
430 | * std::vector. | |
431 | */ | |
92f5a8d4 TL |
432 | template <typename ConstBufferSequence, |
433 | BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, | |
434 | std::size_t)) WriteHandler | |
435 | BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> | |
436 | BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, | |
7c673cae FG |
437 | void (boost::system::error_code, std::size_t)) |
438 | async_send(const ConstBufferSequence& buffers, | |
439 | socket_base::message_flags flags, | |
92f5a8d4 TL |
440 | BOOST_ASIO_MOVE_ARG(WriteHandler) handler |
441 | BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) | |
7c673cae | 442 | { |
92f5a8d4 TL |
443 | return async_initiate<WriteHandler, |
444 | void (boost::system::error_code, std::size_t)>( | |
445 | initiate_async_send(this), handler, buffers, flags); | |
7c673cae FG |
446 | } |
447 | ||
448 | /// Receive some data on the socket. | |
449 | /** | |
450 | * This function is used to receive data on the sequenced packet socket. The | |
451 | * function call will block until data has been received successfully, or | |
452 | * until an error occurs. | |
453 | * | |
454 | * @param buffers One or more buffers into which the data will be received. | |
455 | * | |
456 | * @param out_flags After the receive call completes, contains flags | |
457 | * associated with the received data. For example, if the | |
458 | * socket_base::message_end_of_record bit is set then the received data marks | |
459 | * the end of a record. | |
460 | * | |
461 | * @returns The number of bytes received. | |
462 | * | |
463 | * @throws boost::system::system_error Thrown on failure. An error code of | |
464 | * boost::asio::error::eof indicates that the connection was closed by the | |
465 | * peer. | |
466 | * | |
467 | * @par Example | |
468 | * To receive into a single data buffer use the @ref buffer function as | |
469 | * follows: | |
470 | * @code | |
471 | * socket.receive(boost::asio::buffer(data, size), out_flags); | |
472 | * @endcode | |
473 | * See the @ref buffer documentation for information on receiving into | |
474 | * multiple buffers in one go, and how to use it with arrays, boost::array or | |
475 | * std::vector. | |
476 | */ | |
477 | template <typename MutableBufferSequence> | |
478 | std::size_t receive(const MutableBufferSequence& buffers, | |
479 | socket_base::message_flags& out_flags) | |
480 | { | |
481 | boost::system::error_code ec; | |
92f5a8d4 TL |
482 | std::size_t s = this->impl_.get_service().receive_with_flags( |
483 | this->impl_.get_implementation(), buffers, 0, out_flags, ec); | |
7c673cae FG |
484 | boost::asio::detail::throw_error(ec, "receive"); |
485 | return s; | |
486 | } | |
487 | ||
488 | /// Receive some data on the socket. | |
489 | /** | |
490 | * This function is used to receive data on the sequenced packet socket. The | |
491 | * function call will block until data has been received successfully, or | |
492 | * until an error occurs. | |
493 | * | |
494 | * @param buffers One or more buffers into which the data will be received. | |
495 | * | |
496 | * @param in_flags Flags specifying how the receive call is to be made. | |
497 | * | |
498 | * @param out_flags After the receive call completes, contains flags | |
499 | * associated with the received data. For example, if the | |
500 | * socket_base::message_end_of_record bit is set then the received data marks | |
501 | * the end of a record. | |
502 | * | |
503 | * @returns The number of bytes received. | |
504 | * | |
505 | * @throws boost::system::system_error Thrown on failure. An error code of | |
506 | * boost::asio::error::eof indicates that the connection was closed by the | |
507 | * peer. | |
508 | * | |
509 | * @note The receive operation may not receive all of the requested number of | |
510 | * bytes. Consider using the @ref read function if you need to ensure that the | |
511 | * requested amount of data is read before the blocking operation completes. | |
512 | * | |
513 | * @par Example | |
514 | * To receive into a single data buffer use the @ref buffer function as | |
515 | * follows: | |
516 | * @code | |
517 | * socket.receive(boost::asio::buffer(data, size), 0, out_flags); | |
518 | * @endcode | |
519 | * See the @ref buffer documentation for information on receiving into | |
520 | * multiple buffers in one go, and how to use it with arrays, boost::array or | |
521 | * std::vector. | |
522 | */ | |
523 | template <typename MutableBufferSequence> | |
524 | std::size_t receive(const MutableBufferSequence& buffers, | |
525 | socket_base::message_flags in_flags, | |
526 | socket_base::message_flags& out_flags) | |
527 | { | |
528 | boost::system::error_code ec; | |
92f5a8d4 TL |
529 | std::size_t s = this->impl_.get_service().receive_with_flags( |
530 | this->impl_.get_implementation(), buffers, in_flags, out_flags, ec); | |
7c673cae FG |
531 | boost::asio::detail::throw_error(ec, "receive"); |
532 | return s; | |
533 | } | |
534 | ||
535 | /// Receive some data on a connected socket. | |
536 | /** | |
537 | * This function is used to receive data on the sequenced packet socket. The | |
538 | * function call will block until data has been received successfully, or | |
539 | * until an error occurs. | |
540 | * | |
541 | * @param buffers One or more buffers into which the data will be received. | |
542 | * | |
543 | * @param in_flags Flags specifying how the receive call is to be made. | |
544 | * | |
545 | * @param out_flags After the receive call completes, contains flags | |
546 | * associated with the received data. For example, if the | |
547 | * socket_base::message_end_of_record bit is set then the received data marks | |
548 | * the end of a record. | |
549 | * | |
550 | * @param ec Set to indicate what error occurred, if any. | |
551 | * | |
552 | * @returns The number of bytes received. Returns 0 if an error occurred. | |
553 | * | |
554 | * @note The receive operation may not receive all of the requested number of | |
555 | * bytes. Consider using the @ref read function if you need to ensure that the | |
556 | * requested amount of data is read before the blocking operation completes. | |
557 | */ | |
558 | template <typename MutableBufferSequence> | |
559 | std::size_t receive(const MutableBufferSequence& buffers, | |
560 | socket_base::message_flags in_flags, | |
561 | socket_base::message_flags& out_flags, boost::system::error_code& ec) | |
562 | { | |
92f5a8d4 TL |
563 | return this->impl_.get_service().receive_with_flags( |
564 | this->impl_.get_implementation(), buffers, in_flags, out_flags, ec); | |
7c673cae FG |
565 | } |
566 | ||
567 | /// Start an asynchronous receive. | |
568 | /** | |
569 | * This function is used to asynchronously receive data from the sequenced | |
570 | * packet socket. The function call always returns immediately. | |
571 | * | |
572 | * @param buffers One or more buffers into which the data will be received. | |
573 | * Although the buffers object may be copied as necessary, ownership of the | |
574 | * underlying memory blocks is retained by the caller, which must guarantee | |
575 | * that they remain valid until the handler is called. | |
576 | * | |
577 | * @param out_flags Once the asynchronous operation completes, contains flags | |
578 | * associated with the received data. For example, if the | |
579 | * socket_base::message_end_of_record bit is set then the received data marks | |
580 | * the end of a record. The caller must guarantee that the referenced | |
581 | * variable remains valid until the handler is called. | |
582 | * | |
583 | * @param handler The handler to be called when the receive operation | |
584 | * completes. Copies will be made of the handler as required. The function | |
585 | * signature of the handler must be: | |
586 | * @code void handler( | |
587 | * const boost::system::error_code& error, // Result of operation. | |
588 | * std::size_t bytes_transferred // Number of bytes received. | |
589 | * ); @endcode | |
590 | * Regardless of whether the asynchronous operation completes immediately or | |
92f5a8d4 TL |
591 | * not, the handler will not be invoked from within this function. On |
592 | * immediate completion, invocation of the handler will be performed in a | |
593 | * manner equivalent to using boost::asio::post(). | |
7c673cae FG |
594 | * |
595 | * @par Example | |
596 | * To receive into a single data buffer use the @ref buffer function as | |
597 | * follows: | |
598 | * @code | |
599 | * socket.async_receive(boost::asio::buffer(data, size), out_flags, handler); | |
600 | * @endcode | |
601 | * See the @ref buffer documentation for information on receiving into | |
602 | * multiple buffers in one go, and how to use it with arrays, boost::array or | |
603 | * std::vector. | |
604 | */ | |
92f5a8d4 TL |
605 | template <typename MutableBufferSequence, |
606 | BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, | |
607 | std::size_t)) ReadHandler | |
608 | BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> | |
609 | BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, | |
7c673cae FG |
610 | void (boost::system::error_code, std::size_t)) |
611 | async_receive(const MutableBufferSequence& buffers, | |
612 | socket_base::message_flags& out_flags, | |
92f5a8d4 TL |
613 | BOOST_ASIO_MOVE_ARG(ReadHandler) handler |
614 | BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) | |
7c673cae | 615 | { |
92f5a8d4 TL |
616 | return async_initiate<ReadHandler, |
617 | void (boost::system::error_code, std::size_t)>( | |
618 | initiate_async_receive_with_flags(this), handler, | |
619 | buffers, socket_base::message_flags(0), &out_flags); | |
7c673cae FG |
620 | } |
621 | ||
622 | /// Start an asynchronous receive. | |
623 | /** | |
624 | * This function is used to asynchronously receive data from the sequenced | |
625 | * data socket. The function call always returns immediately. | |
626 | * | |
627 | * @param buffers One or more buffers into which the data will be received. | |
628 | * Although the buffers object may be copied as necessary, ownership of the | |
629 | * underlying memory blocks is retained by the caller, which must guarantee | |
630 | * that they remain valid until the handler is called. | |
631 | * | |
632 | * @param in_flags Flags specifying how the receive call is to be made. | |
633 | * | |
634 | * @param out_flags Once the asynchronous operation completes, contains flags | |
635 | * associated with the received data. For example, if the | |
636 | * socket_base::message_end_of_record bit is set then the received data marks | |
637 | * the end of a record. The caller must guarantee that the referenced | |
638 | * variable remains valid until the handler is called. | |
639 | * | |
640 | * @param handler The handler to be called when the receive operation | |
641 | * completes. Copies will be made of the handler as required. The function | |
642 | * signature of the handler must be: | |
643 | * @code void handler( | |
644 | * const boost::system::error_code& error, // Result of operation. | |
645 | * std::size_t bytes_transferred // Number of bytes received. | |
646 | * ); @endcode | |
647 | * Regardless of whether the asynchronous operation completes immediately or | |
92f5a8d4 TL |
648 | * not, the handler will not be invoked from within this function. On |
649 | * immediate completion, invocation of the handler will be performed in a | |
650 | * manner equivalent to using boost::asio::post(). | |
7c673cae FG |
651 | * |
652 | * @par Example | |
653 | * To receive into a single data buffer use the @ref buffer function as | |
654 | * follows: | |
655 | * @code | |
656 | * socket.async_receive( | |
657 | * boost::asio::buffer(data, size), | |
658 | * 0, out_flags, handler); | |
659 | * @endcode | |
660 | * See the @ref buffer documentation for information on receiving into | |
661 | * multiple buffers in one go, and how to use it with arrays, boost::array or | |
662 | * std::vector. | |
663 | */ | |
92f5a8d4 TL |
664 | template <typename MutableBufferSequence, |
665 | BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code, | |
666 | std::size_t)) ReadHandler | |
667 | BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> | |
668 | BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, | |
7c673cae FG |
669 | void (boost::system::error_code, std::size_t)) |
670 | async_receive(const MutableBufferSequence& buffers, | |
671 | socket_base::message_flags in_flags, | |
672 | socket_base::message_flags& out_flags, | |
92f5a8d4 TL |
673 | BOOST_ASIO_MOVE_ARG(ReadHandler) handler |
674 | BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) | |
7c673cae | 675 | { |
92f5a8d4 TL |
676 | return async_initiate<ReadHandler, |
677 | void (boost::system::error_code, std::size_t)>( | |
678 | initiate_async_receive_with_flags(this), | |
679 | handler, buffers, in_flags, &out_flags); | |
7c673cae | 680 | } |
92f5a8d4 TL |
681 | |
682 | private: | |
20effc67 TL |
683 | // Disallow copying and assignment. |
684 | basic_seq_packet_socket(const basic_seq_packet_socket&) BOOST_ASIO_DELETED; | |
685 | basic_seq_packet_socket& operator=( | |
686 | const basic_seq_packet_socket&) BOOST_ASIO_DELETED; | |
687 | ||
92f5a8d4 TL |
688 | class initiate_async_send |
689 | { | |
690 | public: | |
691 | typedef Executor executor_type; | |
692 | ||
693 | explicit initiate_async_send(basic_seq_packet_socket* self) | |
694 | : self_(self) | |
695 | { | |
696 | } | |
697 | ||
698 | executor_type get_executor() const BOOST_ASIO_NOEXCEPT | |
699 | { | |
700 | return self_->get_executor(); | |
701 | } | |
702 | ||
703 | template <typename WriteHandler, typename ConstBufferSequence> | |
704 | void operator()(BOOST_ASIO_MOVE_ARG(WriteHandler) handler, | |
705 | const ConstBufferSequence& buffers, | |
706 | socket_base::message_flags flags) const | |
707 | { | |
708 | // If you get an error on the following line it means that your handler | |
709 | // does not meet the documented type requirements for a WriteHandler. | |
710 | BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; | |
711 | ||
712 | detail::non_const_lvalue<WriteHandler> handler2(handler); | |
713 | self_->impl_.get_service().async_send( | |
714 | self_->impl_.get_implementation(), buffers, flags, | |
20effc67 | 715 | handler2.value, self_->impl_.get_executor()); |
92f5a8d4 TL |
716 | } |
717 | ||
718 | private: | |
719 | basic_seq_packet_socket* self_; | |
720 | }; | |
721 | ||
722 | class initiate_async_receive_with_flags | |
723 | { | |
724 | public: | |
725 | typedef Executor executor_type; | |
726 | ||
727 | explicit initiate_async_receive_with_flags(basic_seq_packet_socket* self) | |
728 | : self_(self) | |
729 | { | |
730 | } | |
731 | ||
732 | executor_type get_executor() const BOOST_ASIO_NOEXCEPT | |
733 | { | |
734 | return self_->get_executor(); | |
735 | } | |
736 | ||
737 | template <typename ReadHandler, typename MutableBufferSequence> | |
738 | void operator()(BOOST_ASIO_MOVE_ARG(ReadHandler) handler, | |
739 | const MutableBufferSequence& buffers, | |
740 | socket_base::message_flags in_flags, | |
741 | socket_base::message_flags* out_flags) const | |
742 | { | |
743 | // If you get an error on the following line it means that your handler | |
744 | // does not meet the documented type requirements for a ReadHandler. | |
745 | BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; | |
746 | ||
747 | detail::non_const_lvalue<ReadHandler> handler2(handler); | |
748 | self_->impl_.get_service().async_receive_with_flags( | |
20effc67 TL |
749 | self_->impl_.get_implementation(), buffers, in_flags, |
750 | *out_flags, handler2.value, self_->impl_.get_executor()); | |
92f5a8d4 TL |
751 | } |
752 | ||
753 | private: | |
754 | basic_seq_packet_socket* self_; | |
755 | }; | |
7c673cae FG |
756 | }; |
757 | ||
758 | } // namespace asio | |
759 | } // namespace boost | |
760 | ||
761 | #include <boost/asio/detail/pop_options.hpp> | |
762 | ||
763 | #endif // BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_HPP |