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