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