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