1 // 2 // basic_seq_packet_socket.hpp 3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2020 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_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> 24 25 #include <boost/asio/detail/push_options.hpp> 26 27 namespace boost { 28 namespace asio { 29 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. 34 template <typename Protocol, typename Executor = any_io_executor> 35 class basic_seq_packet_socket; 36 37 #endif // !defined(BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_FWD_DECL) 38 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 */ 48 template <typename Protocol, typename Executor> 49 class basic_seq_packet_socket 50 : public basic_socket<Protocol, Executor> 51 { 52 public: 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 64 /// The native representation of a socket. 65 #if defined(GENERATING_DOCUMENTATION) 66 typedef implementation_defined native_handle_type; 67 #else 68 typedef typename basic_socket<Protocol, 69 Executor>::native_handle_type native_handle_type; 70 #endif 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 * 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 */ basic_seq_packet_socket(const executor_type & ex)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. 101 */ 102 template <typename ExecutionContext> basic_seq_packet_socket(ExecutionContext & context,typename enable_if<is_convertible<ExecutionContext &,execution_context &>::value>::type * =0)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) 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 * 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. 119 * 120 * @param protocol An object specifying protocol parameters to be used. 121 * 122 * @throws boost::system::system_error Thrown on failure. 123 */ basic_seq_packet_socket(const executor_type & ex,const protocol_type & protocol)124 basic_seq_packet_socket(const executor_type& ex, 125 const protocol_type& protocol) 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> basic_seq_packet_socket(ExecutionContext & context,const protocol_type & protocol,typename enable_if<is_convertible<ExecutionContext &,execution_context &>::value>::type * =0)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) 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 * 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. 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 */ basic_seq_packet_socket(const executor_type & ex,const endpoint_type & endpoint)169 basic_seq_packet_socket(const executor_type& ex, 170 const endpoint_type& endpoint) 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> basic_seq_packet_socket(ExecutionContext & context,const endpoint_type & endpoint,typename enable_if<is_convertible<ExecutionContext &,execution_context &>::value>::type * =0)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) 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 * 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. 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 */ basic_seq_packet_socket(const executor_type & ex,const protocol_type & protocol,const native_handle_type & native_socket)215 basic_seq_packet_socket(const executor_type& ex, 216 const protocol_type& protocol, const native_handle_type& native_socket) 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> basic_seq_packet_socket(ExecutionContext & context,const protocol_type & protocol,const native_handle_type & native_socket,typename enable_if<is_convertible<ExecutionContext &,execution_context &>::value>::type * =0)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) 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 256 * constructed using the @c basic_seq_packet_socket(const executor_type&) 257 * constructor. 258 */ basic_seq_packet_socket(basic_seq_packet_socket && other)259 basic_seq_packet_socket(basic_seq_packet_socket&& other) BOOST_ASIO_NOEXCEPT 260 : basic_socket<Protocol, Executor>(std::move(other)) 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 273 * constructed using the @c basic_seq_packet_socket(const executor_type&) 274 * constructor. 275 */ operator =(basic_seq_packet_socket && other)276 basic_seq_packet_socket& operator=(basic_seq_packet_socket&& other) 277 { 278 basic_socket<Protocol, Executor>::operator=(std::move(other)); 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 292 * constructed using the @c basic_seq_packet_socket(const executor_type&) 293 * constructor. 294 */ 295 template <typename Protocol1, typename Executor1> basic_seq_packet_socket(basic_seq_packet_socket<Protocol1,Executor1> && other,typename enable_if<is_convertible<Protocol1,Protocol>::value && is_convertible<Executor1,Executor>::value>::type * =0)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)) 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 315 * constructed using the @c basic_seq_packet_socket(const executor_type&) 316 * constructor. 317 */ 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& operator =(basic_seq_packet_socket<Protocol1,Executor1> && other)323 >::type operator=(basic_seq_packet_socket<Protocol1, Executor1>&& other) 324 { 325 basic_socket<Protocol, Executor>::operator=(std::move(other)); 326 return *this; 327 } 328 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) 329 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 */ ~basic_seq_packet_socket()335 ~basic_seq_packet_socket() 336 { 337 } 338 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> send(const ConstBufferSequence & buffers,socket_base::message_flags flags)363 std::size_t send(const ConstBufferSequence& buffers, 364 socket_base::message_flags flags) 365 { 366 boost::system::error_code ec; 367 std::size_t s = this->impl_.get_service().send( 368 this->impl_.get_implementation(), buffers, flags, ec); 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> send(const ConstBufferSequence & buffers,socket_base::message_flags flags,boost::system::error_code & ec)392 std::size_t send(const ConstBufferSequence& buffers, 393 socket_base::message_flags flags, boost::system::error_code& ec) 394 { 395 return this->impl_.get_service().send( 396 this->impl_.get_implementation(), buffers, flags, ec); 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 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(). 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 */ 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)> BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler,void (boost::system::error_code,std::size_t))436 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WriteHandler, 437 void (boost::system::error_code, std::size_t)) 438 async_send(const ConstBufferSequence& buffers, 439 socket_base::message_flags flags, 440 BOOST_ASIO_MOVE_ARG(WriteHandler) handler 441 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) 442 { 443 return async_initiate<WriteHandler, 444 void (boost::system::error_code, std::size_t)>( 445 initiate_async_send(this), handler, buffers, flags); 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> receive(const MutableBufferSequence & buffers,socket_base::message_flags & out_flags)478 std::size_t receive(const MutableBufferSequence& buffers, 479 socket_base::message_flags& out_flags) 480 { 481 boost::system::error_code ec; 482 std::size_t s = this->impl_.get_service().receive_with_flags( 483 this->impl_.get_implementation(), buffers, 0, out_flags, ec); 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> receive(const MutableBufferSequence & buffers,socket_base::message_flags in_flags,socket_base::message_flags & out_flags)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; 529 std::size_t s = this->impl_.get_service().receive_with_flags( 530 this->impl_.get_implementation(), buffers, in_flags, out_flags, ec); 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> receive(const MutableBufferSequence & buffers,socket_base::message_flags in_flags,socket_base::message_flags & out_flags,boost::system::error_code & ec)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 { 563 return this->impl_.get_service().receive_with_flags( 564 this->impl_.get_implementation(), buffers, in_flags, out_flags, ec); 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 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(). 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 */ 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)> BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,void (boost::system::error_code,std::size_t))609 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, 610 void (boost::system::error_code, std::size_t)) 611 async_receive(const MutableBufferSequence& buffers, 612 socket_base::message_flags& out_flags, 613 BOOST_ASIO_MOVE_ARG(ReadHandler) handler 614 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) 615 { 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); 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 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(). 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 */ 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)> BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler,void (boost::system::error_code,std::size_t))668 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ReadHandler, 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, 673 BOOST_ASIO_MOVE_ARG(ReadHandler) handler 674 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) 675 { 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); 680 } 681 682 private: 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 688 class initiate_async_send 689 { 690 public: 691 typedef Executor executor_type; 692 initiate_async_send(basic_seq_packet_socket * self)693 explicit initiate_async_send(basic_seq_packet_socket* self) 694 : self_(self) 695 { 696 } 697 get_executor() const698 executor_type get_executor() const BOOST_ASIO_NOEXCEPT 699 { 700 return self_->get_executor(); 701 } 702 703 template <typename WriteHandler, typename ConstBufferSequence> operator ()(BOOST_ASIO_MOVE_ARG (WriteHandler)handler,const ConstBufferSequence & buffers,socket_base::message_flags flags) const704 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, 715 handler2.value, self_->impl_.get_executor()); 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 initiate_async_receive_with_flags(basic_seq_packet_socket * self)727 explicit initiate_async_receive_with_flags(basic_seq_packet_socket* self) 728 : self_(self) 729 { 730 } 731 get_executor() const732 executor_type get_executor() const BOOST_ASIO_NOEXCEPT 733 { 734 return self_->get_executor(); 735 } 736 737 template <typename ReadHandler, typename MutableBufferSequence> operator ()(BOOST_ASIO_MOVE_ARG (ReadHandler)handler,const MutableBufferSequence & buffers,socket_base::message_flags in_flags,socket_base::message_flags * out_flags) const738 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( 749 self_->impl_.get_implementation(), buffers, in_flags, 750 *out_flags, handler2.value, self_->impl_.get_executor()); 751 } 752 753 private: 754 basic_seq_packet_socket* self_; 755 }; 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 764