1 // 2 // basic_seq_packet_socket.hpp 3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) 6 // 7 // Distributed under the Boost Software License, Version 1.0. (See accompanying 8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 // 10 11 #ifndef BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_HPP 12 #define BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_HPP 13 14 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 15 # pragma once 16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 17 18 #include <boost/asio/detail/config.hpp> 19 #include <cstddef> 20 #include <boost/asio/basic_socket.hpp> 21 #include <boost/asio/detail/handler_type_requirements.hpp> 22 #include <boost/asio/detail/throw_error.hpp> 23 #include <boost/asio/error.hpp> 24 #include <boost/asio/seq_packet_socket_service.hpp> 25 26 #include <boost/asio/detail/push_options.hpp> 27 28 namespace boost { 29 namespace asio { 30 31 /// Provides sequenced packet socket functionality. 32 /** 33 * The basic_seq_packet_socket class template provides asynchronous and blocking 34 * sequenced packet socket functionality. 35 * 36 * @par Thread Safety 37 * @e Distinct @e objects: Safe.@n 38 * @e Shared @e objects: Unsafe. 39 */ 40 template <typename Protocol, 41 typename SeqPacketSocketService = seq_packet_socket_service<Protocol> > 42 class basic_seq_packet_socket 43 : public basic_socket<Protocol, SeqPacketSocketService> 44 { 45 public: 46 /// (Deprecated: Use native_handle_type.) The native representation of a 47 /// socket. 48 typedef typename SeqPacketSocketService::native_handle_type native_type; 49 50 /// The native representation of a socket. 51 typedef typename SeqPacketSocketService::native_handle_type 52 native_handle_type; 53 54 /// The protocol type. 55 typedef Protocol protocol_type; 56 57 /// The endpoint type. 58 typedef typename Protocol::endpoint endpoint_type; 59 60 /// Construct a basic_seq_packet_socket without opening it. 61 /** 62 * This constructor creates a sequenced packet socket without opening it. The 63 * socket needs to be opened and then connected or accepted before data can 64 * be sent or received on it. 65 * 66 * @param io_service The io_service object that the sequenced packet socket 67 * will use to dispatch handlers for any asynchronous operations performed on 68 * the socket. 69 */ basic_seq_packet_socket(boost::asio::io_service & io_service)70 explicit basic_seq_packet_socket(boost::asio::io_service& io_service) 71 : basic_socket<Protocol, SeqPacketSocketService>(io_service) 72 { 73 } 74 75 /// Construct and open a basic_seq_packet_socket. 76 /** 77 * This constructor creates and opens a sequenced_packet socket. The socket 78 * needs to be connected or accepted before data can be sent or received on 79 * it. 80 * 81 * @param io_service The io_service object that the sequenced packet socket 82 * will use to dispatch handlers for any asynchronous operations performed on 83 * the socket. 84 * 85 * @param protocol An object specifying protocol parameters to be used. 86 * 87 * @throws boost::system::system_error Thrown on failure. 88 */ basic_seq_packet_socket(boost::asio::io_service & io_service,const protocol_type & protocol)89 basic_seq_packet_socket(boost::asio::io_service& io_service, 90 const protocol_type& protocol) 91 : basic_socket<Protocol, SeqPacketSocketService>(io_service, protocol) 92 { 93 } 94 95 /// Construct a basic_seq_packet_socket, opening it and binding it to the 96 /// given local endpoint. 97 /** 98 * This constructor creates a sequenced packet socket and automatically opens 99 * it bound to the specified endpoint on the local machine. The protocol used 100 * is the protocol associated with the given endpoint. 101 * 102 * @param io_service The io_service object that the sequenced packet socket 103 * will use to dispatch handlers for any asynchronous operations performed on 104 * the socket. 105 * 106 * @param endpoint An endpoint on the local machine to which the sequenced 107 * packet socket will be bound. 108 * 109 * @throws boost::system::system_error Thrown on failure. 110 */ basic_seq_packet_socket(boost::asio::io_service & io_service,const endpoint_type & endpoint)111 basic_seq_packet_socket(boost::asio::io_service& io_service, 112 const endpoint_type& endpoint) 113 : basic_socket<Protocol, SeqPacketSocketService>(io_service, endpoint) 114 { 115 } 116 117 /// Construct a basic_seq_packet_socket on an existing native socket. 118 /** 119 * This constructor creates a sequenced packet socket object to hold an 120 * existing native socket. 121 * 122 * @param io_service The io_service object that the sequenced packet socket 123 * will use to dispatch handlers for any asynchronous operations performed on 124 * the socket. 125 * 126 * @param protocol An object specifying protocol parameters to be used. 127 * 128 * @param native_socket The new underlying socket implementation. 129 * 130 * @throws boost::system::system_error Thrown on failure. 131 */ basic_seq_packet_socket(boost::asio::io_service & io_service,const protocol_type & protocol,const native_handle_type & native_socket)132 basic_seq_packet_socket(boost::asio::io_service& io_service, 133 const protocol_type& protocol, const native_handle_type& native_socket) 134 : basic_socket<Protocol, SeqPacketSocketService>( 135 io_service, protocol, native_socket) 136 { 137 } 138 139 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) 140 /// Move-construct a basic_seq_packet_socket from another. 141 /** 142 * This constructor moves a sequenced packet socket from one object to 143 * another. 144 * 145 * @param other The other basic_seq_packet_socket object from which the move 146 * will occur. 147 * 148 * @note Following the move, the moved-from object is in the same state as if 149 * constructed using the @c basic_seq_packet_socket(io_service&) constructor. 150 */ basic_seq_packet_socket(basic_seq_packet_socket && other)151 basic_seq_packet_socket(basic_seq_packet_socket&& other) 152 : basic_socket<Protocol, SeqPacketSocketService>( 153 BOOST_ASIO_MOVE_CAST(basic_seq_packet_socket)(other)) 154 { 155 } 156 157 /// Move-assign a basic_seq_packet_socket from another. 158 /** 159 * This assignment operator moves a sequenced packet socket from one object to 160 * another. 161 * 162 * @param other The other basic_seq_packet_socket object from which the move 163 * will occur. 164 * 165 * @note Following the move, the moved-from object is in the same state as if 166 * constructed using the @c basic_seq_packet_socket(io_service&) constructor. 167 */ operator =(basic_seq_packet_socket && other)168 basic_seq_packet_socket& operator=(basic_seq_packet_socket&& other) 169 { 170 basic_socket<Protocol, SeqPacketSocketService>::operator=( 171 BOOST_ASIO_MOVE_CAST(basic_seq_packet_socket)(other)); 172 return *this; 173 } 174 175 /// Move-construct a basic_seq_packet_socket from a socket of another protocol 176 /// type. 177 /** 178 * This constructor moves a sequenced packet socket from one object to 179 * another. 180 * 181 * @param other The other basic_seq_packet_socket object from which the move 182 * will occur. 183 * 184 * @note Following the move, the moved-from object is in the same state as if 185 * constructed using the @c basic_seq_packet_socket(io_service&) constructor. 186 */ 187 template <typename Protocol1, typename SeqPacketSocketService1> basic_seq_packet_socket(basic_seq_packet_socket<Protocol1,SeqPacketSocketService1> && other,typename enable_if<is_convertible<Protocol1,Protocol>::value>::type * =0)188 basic_seq_packet_socket( 189 basic_seq_packet_socket<Protocol1, SeqPacketSocketService1>&& other, 190 typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0) 191 : basic_socket<Protocol, SeqPacketSocketService>( 192 BOOST_ASIO_MOVE_CAST2(basic_seq_packet_socket< 193 Protocol1, SeqPacketSocketService1>)(other)) 194 { 195 } 196 197 /// Move-assign a basic_seq_packet_socket from a socket of another protocol 198 /// type. 199 /** 200 * This assignment operator moves a sequenced packet socket from one object to 201 * another. 202 * 203 * @param other The other basic_seq_packet_socket object from which the move 204 * will occur. 205 * 206 * @note Following the move, the moved-from object is in the same state as if 207 * constructed using the @c basic_seq_packet_socket(io_service&) constructor. 208 */ 209 template <typename Protocol1, typename SeqPacketSocketService1> 210 typename enable_if<is_convertible<Protocol1, Protocol>::value, operator =(basic_seq_packet_socket<Protocol1,SeqPacketSocketService1> && other)211 basic_seq_packet_socket>::type& operator=( 212 basic_seq_packet_socket<Protocol1, SeqPacketSocketService1>&& other) 213 { 214 basic_socket<Protocol, SeqPacketSocketService>::operator=( 215 BOOST_ASIO_MOVE_CAST2(basic_seq_packet_socket< 216 Protocol1, SeqPacketSocketService1>)(other)); 217 return *this; 218 } 219 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) 220 221 /// Send some data on the socket. 222 /** 223 * This function is used to send data on the sequenced packet socket. The 224 * function call will block until the data has been sent successfully, or an 225 * until error occurs. 226 * 227 * @param buffers One or more data buffers to be sent on the socket. 228 * 229 * @param flags Flags specifying how the send call is to be made. 230 * 231 * @returns The number of bytes sent. 232 * 233 * @throws boost::system::system_error Thrown on failure. 234 * 235 * @par Example 236 * To send a single data buffer use the @ref buffer function as follows: 237 * @code 238 * socket.send(boost::asio::buffer(data, size), 0); 239 * @endcode 240 * See the @ref buffer documentation for information on sending multiple 241 * buffers in one go, and how to use it with arrays, boost::array or 242 * std::vector. 243 */ 244 template <typename ConstBufferSequence> send(const ConstBufferSequence & buffers,socket_base::message_flags flags)245 std::size_t send(const ConstBufferSequence& buffers, 246 socket_base::message_flags flags) 247 { 248 boost::system::error_code ec; 249 std::size_t s = this->get_service().send( 250 this->get_implementation(), buffers, flags, ec); 251 boost::asio::detail::throw_error(ec, "send"); 252 return s; 253 } 254 255 /// Send some data on the socket. 256 /** 257 * This function is used to send data on the sequenced packet socket. The 258 * function call will block the data has been sent successfully, or an until 259 * error occurs. 260 * 261 * @param buffers One or more data buffers to be sent on the socket. 262 * 263 * @param flags Flags specifying how the send call is to be made. 264 * 265 * @param ec Set to indicate what error occurred, if any. 266 * 267 * @returns The number of bytes sent. Returns 0 if an error occurred. 268 * 269 * @note The send operation may not transmit all of the data to the peer. 270 * Consider using the @ref write function if you need to ensure that all data 271 * is written before the blocking operation completes. 272 */ 273 template <typename ConstBufferSequence> send(const ConstBufferSequence & buffers,socket_base::message_flags flags,boost::system::error_code & ec)274 std::size_t send(const ConstBufferSequence& buffers, 275 socket_base::message_flags flags, boost::system::error_code& ec) 276 { 277 return this->get_service().send( 278 this->get_implementation(), buffers, flags, ec); 279 } 280 281 /// Start an asynchronous send. 282 /** 283 * This function is used to asynchronously send data on the sequenced packet 284 * socket. The function call always returns immediately. 285 * 286 * @param buffers One or more data buffers to be sent on the socket. Although 287 * the buffers object may be copied as necessary, ownership of the underlying 288 * memory blocks is retained by the caller, which must guarantee that they 289 * remain valid until the handler is called. 290 * 291 * @param flags Flags specifying how the send call is to be made. 292 * 293 * @param handler The handler to be called when the send operation completes. 294 * Copies will be made of the handler as required. The function signature of 295 * the handler must be: 296 * @code void handler( 297 * const boost::system::error_code& error, // Result of operation. 298 * std::size_t bytes_transferred // Number of bytes sent. 299 * ); @endcode 300 * Regardless of whether the asynchronous operation completes immediately or 301 * not, the handler will not be invoked from within this function. Invocation 302 * of the handler will be performed in a manner equivalent to using 303 * boost::asio::io_service::post(). 304 * 305 * @par Example 306 * To send a single data buffer use the @ref buffer function as follows: 307 * @code 308 * socket.async_send(boost::asio::buffer(data, size), 0, handler); 309 * @endcode 310 * See the @ref buffer documentation for information on sending multiple 311 * buffers in one go, and how to use it with arrays, boost::array or 312 * std::vector. 313 */ 314 template <typename ConstBufferSequence, typename WriteHandler> BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler,void (boost::system::error_code,std::size_t))315 BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, 316 void (boost::system::error_code, std::size_t)) 317 async_send(const ConstBufferSequence& buffers, 318 socket_base::message_flags flags, 319 BOOST_ASIO_MOVE_ARG(WriteHandler) handler) 320 { 321 // If you get an error on the following line it means that your handler does 322 // not meet the documented type requirements for a WriteHandler. 323 BOOST_ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; 324 325 return this->get_service().async_send(this->get_implementation(), 326 buffers, flags, BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); 327 } 328 329 /// Receive some data on the socket. 330 /** 331 * This function is used to receive data on the sequenced packet socket. The 332 * function call will block until data has been received successfully, or 333 * until an error occurs. 334 * 335 * @param buffers One or more buffers into which the data will be received. 336 * 337 * @param out_flags After the receive call completes, contains flags 338 * associated with the received data. For example, if the 339 * socket_base::message_end_of_record bit is set then the received data marks 340 * the end of a record. 341 * 342 * @returns The number of bytes received. 343 * 344 * @throws boost::system::system_error Thrown on failure. An error code of 345 * boost::asio::error::eof indicates that the connection was closed by the 346 * peer. 347 * 348 * @par Example 349 * To receive into a single data buffer use the @ref buffer function as 350 * follows: 351 * @code 352 * socket.receive(boost::asio::buffer(data, size), out_flags); 353 * @endcode 354 * See the @ref buffer documentation for information on receiving into 355 * multiple buffers in one go, and how to use it with arrays, boost::array or 356 * std::vector. 357 */ 358 template <typename MutableBufferSequence> receive(const MutableBufferSequence & buffers,socket_base::message_flags & out_flags)359 std::size_t receive(const MutableBufferSequence& buffers, 360 socket_base::message_flags& out_flags) 361 { 362 boost::system::error_code ec; 363 std::size_t s = this->get_service().receive( 364 this->get_implementation(), buffers, 0, out_flags, ec); 365 boost::asio::detail::throw_error(ec, "receive"); 366 return s; 367 } 368 369 /// Receive some data on the socket. 370 /** 371 * This function is used to receive data on the sequenced packet socket. The 372 * function call will block until data has been received successfully, or 373 * until an error occurs. 374 * 375 * @param buffers One or more buffers into which the data will be received. 376 * 377 * @param in_flags Flags specifying how the receive call is to be made. 378 * 379 * @param out_flags After the receive call completes, contains flags 380 * associated with the received data. For example, if the 381 * socket_base::message_end_of_record bit is set then the received data marks 382 * the end of a record. 383 * 384 * @returns The number of bytes received. 385 * 386 * @throws boost::system::system_error Thrown on failure. An error code of 387 * boost::asio::error::eof indicates that the connection was closed by the 388 * peer. 389 * 390 * @note The receive operation may not receive all of the requested number of 391 * bytes. Consider using the @ref read function if you need to ensure that the 392 * requested amount of data is read before the blocking operation completes. 393 * 394 * @par Example 395 * To receive into a single data buffer use the @ref buffer function as 396 * follows: 397 * @code 398 * socket.receive(boost::asio::buffer(data, size), 0, out_flags); 399 * @endcode 400 * See the @ref buffer documentation for information on receiving into 401 * multiple buffers in one go, and how to use it with arrays, boost::array or 402 * std::vector. 403 */ 404 template <typename MutableBufferSequence> receive(const MutableBufferSequence & buffers,socket_base::message_flags in_flags,socket_base::message_flags & out_flags)405 std::size_t receive(const MutableBufferSequence& buffers, 406 socket_base::message_flags in_flags, 407 socket_base::message_flags& out_flags) 408 { 409 boost::system::error_code ec; 410 std::size_t s = this->get_service().receive( 411 this->get_implementation(), buffers, in_flags, out_flags, ec); 412 boost::asio::detail::throw_error(ec, "receive"); 413 return s; 414 } 415 416 /// Receive some data on a connected socket. 417 /** 418 * This function is used to receive data on the sequenced packet socket. The 419 * function call will block until data has been received successfully, or 420 * until an error occurs. 421 * 422 * @param buffers One or more buffers into which the data will be received. 423 * 424 * @param in_flags Flags specifying how the receive call is to be made. 425 * 426 * @param out_flags After the receive call completes, contains flags 427 * associated with the received data. For example, if the 428 * socket_base::message_end_of_record bit is set then the received data marks 429 * the end of a record. 430 * 431 * @param ec Set to indicate what error occurred, if any. 432 * 433 * @returns The number of bytes received. Returns 0 if an error occurred. 434 * 435 * @note The receive operation may not receive all of the requested number of 436 * bytes. Consider using the @ref read function if you need to ensure that the 437 * requested amount of data is read before the blocking operation completes. 438 */ 439 template <typename MutableBufferSequence> receive(const MutableBufferSequence & buffers,socket_base::message_flags in_flags,socket_base::message_flags & out_flags,boost::system::error_code & ec)440 std::size_t receive(const MutableBufferSequence& buffers, 441 socket_base::message_flags in_flags, 442 socket_base::message_flags& out_flags, boost::system::error_code& ec) 443 { 444 return this->get_service().receive(this->get_implementation(), 445 buffers, in_flags, out_flags, ec); 446 } 447 448 /// Start an asynchronous receive. 449 /** 450 * This function is used to asynchronously receive data from the sequenced 451 * packet socket. The function call always returns immediately. 452 * 453 * @param buffers One or more buffers into which the data will be received. 454 * Although the buffers object may be copied as necessary, ownership of the 455 * underlying memory blocks is retained by the caller, which must guarantee 456 * that they remain valid until the handler is called. 457 * 458 * @param out_flags Once the asynchronous operation completes, contains flags 459 * associated with the received data. For example, if the 460 * socket_base::message_end_of_record bit is set then the received data marks 461 * the end of a record. The caller must guarantee that the referenced 462 * variable remains valid until the handler is called. 463 * 464 * @param handler The handler to be called when the receive operation 465 * completes. Copies will be made of the handler as required. The function 466 * signature of the handler must be: 467 * @code void handler( 468 * const boost::system::error_code& error, // Result of operation. 469 * std::size_t bytes_transferred // Number of bytes received. 470 * ); @endcode 471 * Regardless of whether the asynchronous operation completes immediately or 472 * not, the handler will not be invoked from within this function. Invocation 473 * of the handler will be performed in a manner equivalent to using 474 * boost::asio::io_service::post(). 475 * 476 * @par Example 477 * To receive into a single data buffer use the @ref buffer function as 478 * follows: 479 * @code 480 * socket.async_receive(boost::asio::buffer(data, size), out_flags, handler); 481 * @endcode 482 * See the @ref buffer documentation for information on receiving into 483 * multiple buffers in one go, and how to use it with arrays, boost::array or 484 * std::vector. 485 */ 486 template <typename MutableBufferSequence, typename ReadHandler> BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,void (boost::system::error_code,std::size_t))487 BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, 488 void (boost::system::error_code, std::size_t)) 489 async_receive(const MutableBufferSequence& buffers, 490 socket_base::message_flags& out_flags, 491 BOOST_ASIO_MOVE_ARG(ReadHandler) handler) 492 { 493 // If you get an error on the following line it means that your handler does 494 // not meet the documented type requirements for a ReadHandler. 495 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; 496 497 return this->get_service().async_receive( 498 this->get_implementation(), buffers, 0, out_flags, 499 BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); 500 } 501 502 /// Start an asynchronous receive. 503 /** 504 * This function is used to asynchronously receive data from the sequenced 505 * data socket. The function call always returns immediately. 506 * 507 * @param buffers One or more buffers into which the data will be received. 508 * Although the buffers object may be copied as necessary, ownership of the 509 * underlying memory blocks is retained by the caller, which must guarantee 510 * that they remain valid until the handler is called. 511 * 512 * @param in_flags Flags specifying how the receive call is to be made. 513 * 514 * @param out_flags Once the asynchronous operation completes, contains flags 515 * associated with the received data. For example, if the 516 * socket_base::message_end_of_record bit is set then the received data marks 517 * the end of a record. The caller must guarantee that the referenced 518 * variable remains valid until the handler is called. 519 * 520 * @param handler The handler to be called when the receive operation 521 * completes. Copies will be made of the handler as required. The function 522 * signature of the handler must be: 523 * @code void handler( 524 * const boost::system::error_code& error, // Result of operation. 525 * std::size_t bytes_transferred // Number of bytes received. 526 * ); @endcode 527 * Regardless of whether the asynchronous operation completes immediately or 528 * not, the handler will not be invoked from within this function. Invocation 529 * of the handler will be performed in a manner equivalent to using 530 * boost::asio::io_service::post(). 531 * 532 * @par Example 533 * To receive into a single data buffer use the @ref buffer function as 534 * follows: 535 * @code 536 * socket.async_receive( 537 * boost::asio::buffer(data, size), 538 * 0, out_flags, handler); 539 * @endcode 540 * See the @ref buffer documentation for information on receiving into 541 * multiple buffers in one go, and how to use it with arrays, boost::array or 542 * std::vector. 543 */ 544 template <typename MutableBufferSequence, typename ReadHandler> BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler,void (boost::system::error_code,std::size_t))545 BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, 546 void (boost::system::error_code, std::size_t)) 547 async_receive(const MutableBufferSequence& buffers, 548 socket_base::message_flags in_flags, 549 socket_base::message_flags& out_flags, 550 BOOST_ASIO_MOVE_ARG(ReadHandler) handler) 551 { 552 // If you get an error on the following line it means that your handler does 553 // not meet the documented type requirements for a ReadHandler. 554 BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; 555 556 return this->get_service().async_receive( 557 this->get_implementation(), buffers, in_flags, out_flags, 558 BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); 559 } 560 }; 561 562 } // namespace asio 563 } // namespace boost 564 565 #include <boost/asio/detail/pop_options.hpp> 566 567 #endif // BOOST_ASIO_BASIC_SEQ_PACKET_SOCKET_HPP 568