1 // 2 // basic_stream_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 ASIO_BASIC_STREAM_SOCKET_HPP 12 #define ASIO_BASIC_STREAM_SOCKET_HPP 13 14 15 #include "asio/detail/config.hpp" 16 #include <cstddef> 17 #include "asio/async_result.hpp" 18 #include "asio/basic_socket.hpp" 19 #include "asio/detail/handler_type_requirements.hpp" 20 #include "asio/detail/throw_error.hpp" 21 #include "asio/error.hpp" 22 #include "asio/stream_socket_service.hpp" 23 24 #include "asio/detail/push_options.hpp" 25 26 namespace asio { 27 28 /// Provides stream-oriented socket functionality. 29 /** 30 * The basic_stream_socket class template provides asynchronous and blocking 31 * stream-oriented socket functionality. 32 * 33 * @par Thread Safety 34 * @e Distinct @e objects: Safe.@n 35 * @e Shared @e objects: Unsafe. 36 * 37 * @par Concepts: 38 * AsyncReadStream, AsyncWriteStream, Stream, SyncReadStream, SyncWriteStream. 39 */ 40 template <typename Protocol, 41 typename StreamSocketService = stream_socket_service<Protocol> > 42 class basic_stream_socket 43 : public basic_socket<Protocol, StreamSocketService> 44 { 45 public: 46 /// (Deprecated: Use native_handle_type.) The native representation of a 47 /// socket. 48 typedef typename StreamSocketService::native_handle_type native_type; 49 50 /// The native representation of a socket. 51 typedef typename StreamSocketService::native_handle_type native_handle_type; 52 53 /// The protocol type. 54 typedef Protocol protocol_type; 55 56 /// The endpoint type. 57 typedef typename Protocol::endpoint endpoint_type; 58 59 /// Construct a basic_stream_socket without opening it. 60 /** 61 * This constructor creates a stream socket without opening it. The socket 62 * needs to be opened and then connected or accepted before data can be sent 63 * or received on it. 64 * 65 * @param io_service The io_service object that the stream socket will use to 66 * dispatch handlers for any asynchronous operations performed on the socket. 67 */ basic_stream_socket(asio::io_service & io_service)68 explicit basic_stream_socket(asio::io_service& io_service) 69 : basic_socket<Protocol, StreamSocketService>(io_service) 70 { 71 } 72 73 /// Construct and open a basic_stream_socket. 74 /** 75 * This constructor creates and opens a stream socket. The socket needs to be 76 * connected or accepted before data can be sent or received on it. 77 * 78 * @param io_service The io_service object that the stream socket will use to 79 * dispatch handlers for any asynchronous operations performed on the socket. 80 * 81 * @param protocol An object specifying protocol parameters to be used. 82 * 83 * @throws asio::system_error Thrown on failure. 84 */ basic_stream_socket(asio::io_service & io_service,const protocol_type & protocol)85 basic_stream_socket(asio::io_service& io_service, 86 const protocol_type& protocol) 87 : basic_socket<Protocol, StreamSocketService>(io_service, protocol) 88 { 89 } 90 91 /// Construct a basic_stream_socket, opening it and binding it to the given 92 /// local endpoint. 93 /** 94 * This constructor creates a stream socket and automatically opens it bound 95 * to the specified endpoint on the local machine. The protocol used is the 96 * protocol associated with the given endpoint. 97 * 98 * @param io_service The io_service object that the stream socket will use to 99 * dispatch handlers for any asynchronous operations performed on the socket. 100 * 101 * @param endpoint An endpoint on the local machine to which the stream 102 * socket will be bound. 103 * 104 * @throws asio::system_error Thrown on failure. 105 */ basic_stream_socket(asio::io_service & io_service,const endpoint_type & endpoint)106 basic_stream_socket(asio::io_service& io_service, 107 const endpoint_type& endpoint) 108 : basic_socket<Protocol, StreamSocketService>(io_service, endpoint) 109 { 110 } 111 112 /// Construct a basic_stream_socket on an existing native socket. 113 /** 114 * This constructor creates a stream socket object to hold an existing native 115 * socket. 116 * 117 * @param io_service The io_service object that the stream socket will use to 118 * dispatch handlers for any asynchronous operations performed on the socket. 119 * 120 * @param protocol An object specifying protocol parameters to be used. 121 * 122 * @param native_socket The new underlying socket implementation. 123 * 124 * @throws asio::system_error Thrown on failure. 125 */ basic_stream_socket(asio::io_service & io_service,const protocol_type & protocol,const native_handle_type & native_socket)126 basic_stream_socket(asio::io_service& io_service, 127 const protocol_type& protocol, const native_handle_type& native_socket) 128 : basic_socket<Protocol, StreamSocketService>( 129 io_service, protocol, native_socket) 130 { 131 } 132 133 /// Move-construct a basic_stream_socket from another. 134 /** 135 * This constructor moves a stream socket from one object to another. 136 * 137 * @param other The other basic_stream_socket object from which the move 138 * will occur. 139 * 140 * @note Following the move, the moved-from object is in the same state as if 141 * constructed using the @c basic_stream_socket(io_service&) constructor. 142 */ basic_stream_socket(basic_stream_socket && other)143 basic_stream_socket(basic_stream_socket&& other) 144 : basic_socket<Protocol, StreamSocketService>( 145 ASIO_MOVE_CAST(basic_stream_socket)(other)) 146 { 147 } 148 149 /// Move-assign a basic_stream_socket from another. 150 /** 151 * This assignment operator moves a stream socket from one object to another. 152 * 153 * @param other The other basic_stream_socket object from which the move 154 * will occur. 155 * 156 * @note Following the move, the moved-from object is in the same state as if 157 * constructed using the @c basic_stream_socket(io_service&) constructor. 158 */ operator =(basic_stream_socket && other)159 basic_stream_socket& operator=(basic_stream_socket&& other) 160 { 161 basic_socket<Protocol, StreamSocketService>::operator=( 162 ASIO_MOVE_CAST(basic_stream_socket)(other)); 163 return *this; 164 } 165 166 /// Move-construct a basic_stream_socket from a socket of another protocol 167 /// type. 168 /** 169 * This constructor moves a stream socket from one object to another. 170 * 171 * @param other The other basic_stream_socket object from which the move 172 * will occur. 173 * 174 * @note Following the move, the moved-from object is in the same state as if 175 * constructed using the @c basic_stream_socket(io_service&) constructor. 176 */ 177 template <typename Protocol1, typename StreamSocketService1> basic_stream_socket(basic_stream_socket<Protocol1,StreamSocketService1> && other,typename enable_if<is_convertible<Protocol1,Protocol>::value>::type * =0)178 basic_stream_socket( 179 basic_stream_socket<Protocol1, StreamSocketService1>&& other, 180 typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0) 181 : basic_socket<Protocol, StreamSocketService>( 182 ASIO_MOVE_CAST2(basic_stream_socket< 183 Protocol1, StreamSocketService1>)(other)) 184 { 185 } 186 187 /// Move-assign a basic_stream_socket from a socket of another protocol type. 188 /** 189 * This assignment operator moves a stream socket from one object to another. 190 * 191 * @param other The other basic_stream_socket object from which the move 192 * will occur. 193 * 194 * @note Following the move, the moved-from object is in the same state as if 195 * constructed using the @c basic_stream_socket(io_service&) constructor. 196 */ 197 template <typename Protocol1, typename StreamSocketService1> 198 typename enable_if<is_convertible<Protocol1, Protocol>::value, operator =(basic_stream_socket<Protocol1,StreamSocketService1> && other)199 basic_stream_socket>::type& operator=( 200 basic_stream_socket<Protocol1, StreamSocketService1>&& other) 201 { 202 basic_socket<Protocol, StreamSocketService>::operator=( 203 ASIO_MOVE_CAST2(basic_stream_socket< 204 Protocol1, StreamSocketService1>)(other)); 205 return *this; 206 } 207 208 /// Send some data on the socket. 209 /** 210 * This function is used to send data on the stream socket. The function 211 * call will block until one or more bytes of the data has been sent 212 * successfully, or an until error occurs. 213 * 214 * @param buffers One or more data buffers to be sent on the socket. 215 * 216 * @returns The number of bytes sent. 217 * 218 * @throws asio::system_error Thrown on failure. 219 * 220 * @note The send operation may not transmit all of the data to the peer. 221 * Consider using the @ref write function if you need to ensure that all data 222 * is written before the blocking operation completes. 223 * 224 * @par Example 225 * To send a single data buffer use the @ref buffer function as follows: 226 * @code 227 * socket.send(asio::buffer(data, size)); 228 * @endcode 229 * See the @ref buffer documentation for information on sending multiple 230 * buffers in one go, and how to use it with arrays, boost::array or 231 * std::vector. 232 */ 233 template <typename ConstBufferSequence> send(const ConstBufferSequence & buffers)234 std::size_t send(const ConstBufferSequence& buffers) 235 { 236 asio::error_code ec; 237 std::size_t s = this->get_service().send( 238 this->get_implementation(), buffers, 0, ec); 239 asio::detail::throw_error(ec, "send"); 240 return s; 241 } 242 243 /// Send some data on the socket. 244 /** 245 * This function is used to send data on the stream socket. The function 246 * call will block until one or more bytes of the data has been sent 247 * successfully, or an until error occurs. 248 * 249 * @param buffers One or more data buffers to be sent on the socket. 250 * 251 * @param flags Flags specifying how the send call is to be made. 252 * 253 * @returns The number of bytes sent. 254 * 255 * @throws asio::system_error Thrown on failure. 256 * 257 * @note The send operation may not transmit all of the data to the peer. 258 * Consider using the @ref write function if you need to ensure that all data 259 * is written before the blocking operation completes. 260 * 261 * @par Example 262 * To send a single data buffer use the @ref buffer function as follows: 263 * @code 264 * socket.send(asio::buffer(data, size), 0); 265 * @endcode 266 * See the @ref buffer documentation for information on sending multiple 267 * buffers in one go, and how to use it with arrays, boost::array or 268 * std::vector. 269 */ 270 template <typename ConstBufferSequence> send(const ConstBufferSequence & buffers,socket_base::message_flags flags)271 std::size_t send(const ConstBufferSequence& buffers, 272 socket_base::message_flags flags) 273 { 274 asio::error_code ec; 275 std::size_t s = this->get_service().send( 276 this->get_implementation(), buffers, flags, ec); 277 asio::detail::throw_error(ec, "send"); 278 return s; 279 } 280 281 /// Send some data on the socket. 282 /** 283 * This function is used to send data on the stream socket. The function 284 * call will block until one or more bytes of the data has been sent 285 * successfully, or an until error occurs. 286 * 287 * @param buffers One or more data buffers to be sent on the socket. 288 * 289 * @param flags Flags specifying how the send call is to be made. 290 * 291 * @param ec Set to indicate what error occurred, if any. 292 * 293 * @returns The number of bytes sent. Returns 0 if an error occurred. 294 * 295 * @note The send operation may not transmit all of the data to the peer. 296 * Consider using the @ref write function if you need to ensure that all data 297 * is written before the blocking operation completes. 298 */ 299 template <typename ConstBufferSequence> send(const ConstBufferSequence & buffers,socket_base::message_flags flags,asio::error_code & ec)300 std::size_t send(const ConstBufferSequence& buffers, 301 socket_base::message_flags flags, asio::error_code& ec) 302 { 303 return this->get_service().send( 304 this->get_implementation(), buffers, flags, ec); 305 } 306 307 /// Start an asynchronous send. 308 /** 309 * This function is used to asynchronously send data on the stream socket. 310 * The function call always returns immediately. 311 * 312 * @param buffers One or more data buffers to be sent on the socket. Although 313 * the buffers object may be copied as necessary, ownership of the underlying 314 * memory blocks is retained by the caller, which must guarantee that they 315 * remain valid until the handler is called. 316 * 317 * @param handler The handler to be called when the send operation completes. 318 * Copies will be made of the handler as required. The function signature of 319 * the handler must be: 320 * @code void handler( 321 * const asio::error_code& error, // Result of operation. 322 * std::size_t bytes_transferred // Number of bytes sent. 323 * ); @endcode 324 * Regardless of whether the asynchronous operation completes immediately or 325 * not, the handler will not be invoked from within this function. Invocation 326 * of the handler will be performed in a manner equivalent to using 327 * asio::io_service::post(). 328 * 329 * @note The send operation may not transmit all of the data to the peer. 330 * Consider using the @ref async_write function if you need to ensure that all 331 * data is written before the asynchronous operation completes. 332 * 333 * @par Example 334 * To send a single data buffer use the @ref buffer function as follows: 335 * @code 336 * socket.async_send(asio::buffer(data, size), handler); 337 * @endcode 338 * See the @ref buffer documentation for information on sending multiple 339 * buffers in one go, and how to use it with arrays, boost::array or 340 * std::vector. 341 */ 342 template <typename ConstBufferSequence, typename WriteHandler> ASIO_INITFN_RESULT_TYPE(WriteHandler,void (asio::error_code,std::size_t))343 ASIO_INITFN_RESULT_TYPE(WriteHandler, 344 void (asio::error_code, std::size_t)) 345 async_send(const ConstBufferSequence& buffers, 346 ASIO_MOVE_ARG(WriteHandler) handler) 347 { 348 // If you get an error on the following line it means that your handler does 349 // not meet the documented type requirements for a WriteHandler. 350 ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; 351 352 return this->get_service().async_send( 353 this->get_implementation(), buffers, 0, 354 ASIO_MOVE_CAST(WriteHandler)(handler)); 355 } 356 357 /// Start an asynchronous send. 358 /** 359 * This function is used to asynchronously send data on the stream socket. 360 * The function call always returns immediately. 361 * 362 * @param buffers One or more data buffers to be sent on the socket. Although 363 * the buffers object may be copied as necessary, ownership of the underlying 364 * memory blocks is retained by the caller, which must guarantee that they 365 * remain valid until the handler is called. 366 * 367 * @param flags Flags specifying how the send call is to be made. 368 * 369 * @param handler The handler to be called when the send operation completes. 370 * Copies will be made of the handler as required. The function signature of 371 * the handler must be: 372 * @code void handler( 373 * const asio::error_code& error, // Result of operation. 374 * std::size_t bytes_transferred // Number of bytes sent. 375 * ); @endcode 376 * Regardless of whether the asynchronous operation completes immediately or 377 * not, the handler will not be invoked from within this function. Invocation 378 * of the handler will be performed in a manner equivalent to using 379 * asio::io_service::post(). 380 * 381 * @note The send operation may not transmit all of the data to the peer. 382 * Consider using the @ref async_write function if you need to ensure that all 383 * data is written before the asynchronous operation completes. 384 * 385 * @par Example 386 * To send a single data buffer use the @ref buffer function as follows: 387 * @code 388 * socket.async_send(asio::buffer(data, size), 0, handler); 389 * @endcode 390 * See the @ref buffer documentation for information on sending multiple 391 * buffers in one go, and how to use it with arrays, boost::array or 392 * std::vector. 393 */ 394 template <typename ConstBufferSequence, typename WriteHandler> ASIO_INITFN_RESULT_TYPE(WriteHandler,void (asio::error_code,std::size_t))395 ASIO_INITFN_RESULT_TYPE(WriteHandler, 396 void (asio::error_code, std::size_t)) 397 async_send(const ConstBufferSequence& buffers, 398 socket_base::message_flags flags, 399 ASIO_MOVE_ARG(WriteHandler) handler) 400 { 401 // If you get an error on the following line it means that your handler does 402 // not meet the documented type requirements for a WriteHandler. 403 ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; 404 405 return this->get_service().async_send( 406 this->get_implementation(), buffers, flags, 407 ASIO_MOVE_CAST(WriteHandler)(handler)); 408 } 409 410 /// Receive some data on the socket. 411 /** 412 * This function is used to receive data on the stream socket. The function 413 * call will block until one or more bytes of data has been received 414 * successfully, or until an error occurs. 415 * 416 * @param buffers One or more buffers into which the data will be received. 417 * 418 * @returns The number of bytes received. 419 * 420 * @throws asio::system_error Thrown on failure. An error code of 421 * asio::error::eof indicates that the connection was closed by the 422 * peer. 423 * 424 * @note The receive operation may not receive all of the requested number of 425 * bytes. Consider using the @ref read function if you need to ensure that the 426 * requested amount of data is read before the blocking operation completes. 427 * 428 * @par Example 429 * To receive into a single data buffer use the @ref buffer function as 430 * follows: 431 * @code 432 * socket.receive(asio::buffer(data, size)); 433 * @endcode 434 * See the @ref buffer documentation for information on receiving into 435 * multiple buffers in one go, and how to use it with arrays, boost::array or 436 * std::vector. 437 */ 438 template <typename MutableBufferSequence> receive(const MutableBufferSequence & buffers)439 std::size_t receive(const MutableBufferSequence& buffers) 440 { 441 asio::error_code ec; 442 std::size_t s = this->get_service().receive( 443 this->get_implementation(), buffers, 0, ec); 444 asio::detail::throw_error(ec, "receive"); 445 return s; 446 } 447 448 /// Receive some data on the socket. 449 /** 450 * This function is used to receive data on the stream socket. The function 451 * call will block until one or more bytes of data has been received 452 * successfully, or until an error occurs. 453 * 454 * @param buffers One or more buffers into which the data will be received. 455 * 456 * @param flags Flags specifying how the receive call is to be made. 457 * 458 * @returns The number of bytes received. 459 * 460 * @throws asio::system_error Thrown on failure. An error code of 461 * asio::error::eof indicates that the connection was closed by the 462 * peer. 463 * 464 * @note The receive operation may not receive all of the requested number of 465 * bytes. Consider using the @ref read function if you need to ensure that the 466 * requested amount of data is read before the blocking operation completes. 467 * 468 * @par Example 469 * To receive into a single data buffer use the @ref buffer function as 470 * follows: 471 * @code 472 * socket.receive(asio::buffer(data, size), 0); 473 * @endcode 474 * See the @ref buffer documentation for information on receiving into 475 * multiple buffers in one go, and how to use it with arrays, boost::array or 476 * std::vector. 477 */ 478 template <typename MutableBufferSequence> receive(const MutableBufferSequence & buffers,socket_base::message_flags flags)479 std::size_t receive(const MutableBufferSequence& buffers, 480 socket_base::message_flags flags) 481 { 482 asio::error_code ec; 483 std::size_t s = this->get_service().receive( 484 this->get_implementation(), buffers, flags, ec); 485 asio::detail::throw_error(ec, "receive"); 486 return s; 487 } 488 489 /// Receive some data on a connected socket. 490 /** 491 * This function is used to receive data on the stream socket. The function 492 * call will block until one or more bytes of data has been received 493 * successfully, or until an error occurs. 494 * 495 * @param buffers One or more buffers into which the data will be received. 496 * 497 * @param flags Flags specifying how the receive call is to be made. 498 * 499 * @param ec Set to indicate what error occurred, if any. 500 * 501 * @returns The number of bytes received. Returns 0 if an error occurred. 502 * 503 * @note The receive operation may not receive all of the requested number of 504 * bytes. Consider using the @ref read function if you need to ensure that the 505 * requested amount of data is read before the blocking operation completes. 506 */ 507 template <typename MutableBufferSequence> receive(const MutableBufferSequence & buffers,socket_base::message_flags flags,asio::error_code & ec)508 std::size_t receive(const MutableBufferSequence& buffers, 509 socket_base::message_flags flags, asio::error_code& ec) 510 { 511 return this->get_service().receive( 512 this->get_implementation(), buffers, flags, ec); 513 } 514 515 /// Start an asynchronous receive. 516 /** 517 * This function is used to asynchronously receive data from the stream 518 * socket. The function call always returns immediately. 519 * 520 * @param buffers One or more buffers into which the data will be received. 521 * Although the buffers object may be copied as necessary, ownership of the 522 * underlying memory blocks is retained by the caller, which must guarantee 523 * that they remain valid until the handler is called. 524 * 525 * @param handler The handler to be called when the receive operation 526 * completes. Copies will be made of the handler as required. The function 527 * signature of the handler must be: 528 * @code void handler( 529 * const asio::error_code& error, // Result of operation. 530 * std::size_t bytes_transferred // Number of bytes received. 531 * ); @endcode 532 * Regardless of whether the asynchronous operation completes immediately or 533 * not, the handler will not be invoked from within this function. Invocation 534 * of the handler will be performed in a manner equivalent to using 535 * asio::io_service::post(). 536 * 537 * @note The receive operation may not receive all of the requested number of 538 * bytes. Consider using the @ref async_read function if you need to ensure 539 * that the requested amount of data is received before the asynchronous 540 * operation completes. 541 * 542 * @par Example 543 * To receive into a single data buffer use the @ref buffer function as 544 * follows: 545 * @code 546 * socket.async_receive(asio::buffer(data, size), handler); 547 * @endcode 548 * See the @ref buffer documentation for information on receiving into 549 * multiple buffers in one go, and how to use it with arrays, boost::array or 550 * std::vector. 551 */ 552 template <typename MutableBufferSequence, typename ReadHandler> ASIO_INITFN_RESULT_TYPE(ReadHandler,void (asio::error_code,std::size_t))553 ASIO_INITFN_RESULT_TYPE(ReadHandler, 554 void (asio::error_code, std::size_t)) 555 async_receive(const MutableBufferSequence& buffers, 556 ASIO_MOVE_ARG(ReadHandler) handler) 557 { 558 // If you get an error on the following line it means that your handler does 559 // not meet the documented type requirements for a ReadHandler. 560 ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; 561 562 return this->get_service().async_receive(this->get_implementation(), 563 buffers, 0, ASIO_MOVE_CAST(ReadHandler)(handler)); 564 } 565 566 /// Start an asynchronous receive. 567 /** 568 * This function is used to asynchronously receive data from the stream 569 * socket. The function call always returns immediately. 570 * 571 * @param buffers One or more buffers into which the data will be received. 572 * Although the buffers object may be copied as necessary, ownership of the 573 * underlying memory blocks is retained by the caller, which must guarantee 574 * that they remain valid until the handler is called. 575 * 576 * @param flags Flags specifying how the receive call is to be made. 577 * 578 * @param handler The handler to be called when the receive operation 579 * completes. Copies will be made of the handler as required. The function 580 * signature of the handler must be: 581 * @code void handler( 582 * const asio::error_code& error, // Result of operation. 583 * std::size_t bytes_transferred // Number of bytes received. 584 * ); @endcode 585 * Regardless of whether the asynchronous operation completes immediately or 586 * not, the handler will not be invoked from within this function. Invocation 587 * of the handler will be performed in a manner equivalent to using 588 * asio::io_service::post(). 589 * 590 * @note The receive operation may not receive all of the requested number of 591 * bytes. Consider using the @ref async_read function if you need to ensure 592 * that the requested amount of data is received before the asynchronous 593 * operation completes. 594 * 595 * @par Example 596 * To receive into a single data buffer use the @ref buffer function as 597 * follows: 598 * @code 599 * socket.async_receive(asio::buffer(data, size), 0, handler); 600 * @endcode 601 * See the @ref buffer documentation for information on receiving into 602 * multiple buffers in one go, and how to use it with arrays, boost::array or 603 * std::vector. 604 */ 605 template <typename MutableBufferSequence, typename ReadHandler> ASIO_INITFN_RESULT_TYPE(ReadHandler,void (asio::error_code,std::size_t))606 ASIO_INITFN_RESULT_TYPE(ReadHandler, 607 void (asio::error_code, std::size_t)) 608 async_receive(const MutableBufferSequence& buffers, 609 socket_base::message_flags flags, 610 ASIO_MOVE_ARG(ReadHandler) handler) 611 { 612 // If you get an error on the following line it means that your handler does 613 // not meet the documented type requirements for a ReadHandler. 614 ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; 615 616 return this->get_service().async_receive(this->get_implementation(), 617 buffers, flags, ASIO_MOVE_CAST(ReadHandler)(handler)); 618 } 619 620 /// Write some data to the socket. 621 /** 622 * This function is used to write data to the stream socket. The function call 623 * will block until one or more bytes of the data has been written 624 * successfully, or until an error occurs. 625 * 626 * @param buffers One or more data buffers to be written to the socket. 627 * 628 * @returns The number of bytes written. 629 * 630 * @throws asio::system_error Thrown on failure. An error code of 631 * asio::error::eof indicates that the connection was closed by the 632 * peer. 633 * 634 * @note The write_some operation may not transmit all of the data to the 635 * peer. Consider using the @ref write function if you need to ensure that 636 * all data is written before the blocking operation completes. 637 * 638 * @par Example 639 * To write a single data buffer use the @ref buffer function as follows: 640 * @code 641 * socket.write_some(asio::buffer(data, size)); 642 * @endcode 643 * See the @ref buffer documentation for information on writing multiple 644 * buffers in one go, and how to use it with arrays, boost::array or 645 * std::vector. 646 */ 647 template <typename ConstBufferSequence> write_some(const ConstBufferSequence & buffers)648 std::size_t write_some(const ConstBufferSequence& buffers) 649 { 650 asio::error_code ec; 651 std::size_t s = this->get_service().send( 652 this->get_implementation(), buffers, 0, ec); 653 asio::detail::throw_error(ec, "write_some"); 654 return s; 655 } 656 657 /// Write some data to the socket. 658 /** 659 * This function is used to write data to the stream socket. The function call 660 * will block until one or more bytes of the data has been written 661 * successfully, or until an error occurs. 662 * 663 * @param buffers One or more data buffers to be written to the socket. 664 * 665 * @param ec Set to indicate what error occurred, if any. 666 * 667 * @returns The number of bytes written. Returns 0 if an error occurred. 668 * 669 * @note The write_some operation may not transmit all of the data to the 670 * peer. Consider using the @ref write function if you need to ensure that 671 * all data is written before the blocking operation completes. 672 */ 673 template <typename ConstBufferSequence> write_some(const ConstBufferSequence & buffers,asio::error_code & ec)674 std::size_t write_some(const ConstBufferSequence& buffers, 675 asio::error_code& ec) 676 { 677 return this->get_service().send(this->get_implementation(), buffers, 0, ec); 678 } 679 680 /// Start an asynchronous write. 681 /** 682 * This function is used to asynchronously write data to the stream socket. 683 * The function call always returns immediately. 684 * 685 * @param buffers One or more data buffers to be written to the socket. 686 * Although the buffers object may be copied as necessary, ownership of the 687 * underlying memory blocks is retained by the caller, which must guarantee 688 * that they remain valid until the handler is called. 689 * 690 * @param handler The handler to be called when the write operation completes. 691 * Copies will be made of the handler as required. The function signature of 692 * the handler must be: 693 * @code void handler( 694 * const asio::error_code& error, // Result of operation. 695 * std::size_t bytes_transferred // Number of bytes written. 696 * ); @endcode 697 * Regardless of whether the asynchronous operation completes immediately or 698 * not, the handler will not be invoked from within this function. Invocation 699 * of the handler will be performed in a manner equivalent to using 700 * asio::io_service::post(). 701 * 702 * @note The write operation may not transmit all of the data to the peer. 703 * Consider using the @ref async_write function if you need to ensure that all 704 * data is written before the asynchronous operation completes. 705 * 706 * @par Example 707 * To write a single data buffer use the @ref buffer function as follows: 708 * @code 709 * socket.async_write_some(asio::buffer(data, size), handler); 710 * @endcode 711 * See the @ref buffer documentation for information on writing multiple 712 * buffers in one go, and how to use it with arrays, boost::array or 713 * std::vector. 714 */ 715 template <typename ConstBufferSequence, typename WriteHandler> ASIO_INITFN_RESULT_TYPE(WriteHandler,void (asio::error_code,std::size_t))716 ASIO_INITFN_RESULT_TYPE(WriteHandler, 717 void (asio::error_code, std::size_t)) 718 async_write_some(const ConstBufferSequence& buffers, 719 ASIO_MOVE_ARG(WriteHandler) handler) 720 { 721 // If you get an error on the following line it means that your handler does 722 // not meet the documented type requirements for a WriteHandler. 723 ASIO_WRITE_HANDLER_CHECK(WriteHandler, handler) type_check; 724 725 return this->get_service().async_send(this->get_implementation(), 726 buffers, 0, ASIO_MOVE_CAST(WriteHandler)(handler)); 727 } 728 729 /// Read some data from the socket. 730 /** 731 * This function is used to read data from the stream socket. The function 732 * call will block until one or more bytes of data has been read successfully, 733 * or until an error occurs. 734 * 735 * @param buffers One or more buffers into which the data will be read. 736 * 737 * @returns The number of bytes read. 738 * 739 * @throws asio::system_error Thrown on failure. An error code of 740 * asio::error::eof indicates that the connection was closed by the 741 * peer. 742 * 743 * @note The read_some operation may not read all of the requested number of 744 * bytes. Consider using the @ref read function if you need to ensure that 745 * the requested amount of data is read before the blocking operation 746 * completes. 747 * 748 * @par Example 749 * To read into a single data buffer use the @ref buffer function as follows: 750 * @code 751 * socket.read_some(asio::buffer(data, size)); 752 * @endcode 753 * See the @ref buffer documentation for information on reading into multiple 754 * buffers in one go, and how to use it with arrays, boost::array or 755 * std::vector. 756 */ 757 template <typename MutableBufferSequence> read_some(const MutableBufferSequence & buffers)758 std::size_t read_some(const MutableBufferSequence& buffers) 759 { 760 asio::error_code ec; 761 std::size_t s = this->get_service().receive( 762 this->get_implementation(), buffers, 0, ec); 763 asio::detail::throw_error(ec, "read_some"); 764 return s; 765 } 766 767 /// Read some data from the socket. 768 /** 769 * This function is used to read data from the stream socket. The function 770 * call will block until one or more bytes of data has been read successfully, 771 * or until an error occurs. 772 * 773 * @param buffers One or more buffers into which the data will be read. 774 * 775 * @param ec Set to indicate what error occurred, if any. 776 * 777 * @returns The number of bytes read. Returns 0 if an error occurred. 778 * 779 * @note The read_some operation may not read all of the requested number of 780 * bytes. Consider using the @ref read function if you need to ensure that 781 * the requested amount of data is read before the blocking operation 782 * completes. 783 */ 784 template <typename MutableBufferSequence> read_some(const MutableBufferSequence & buffers,asio::error_code & ec)785 std::size_t read_some(const MutableBufferSequence& buffers, 786 asio::error_code& ec) 787 { 788 return this->get_service().receive( 789 this->get_implementation(), buffers, 0, ec); 790 } 791 792 /// Start an asynchronous read. 793 /** 794 * This function is used to asynchronously read data from the stream socket. 795 * The function call always returns immediately. 796 * 797 * @param buffers One or more buffers into which the data will be read. 798 * Although the buffers object may be copied as necessary, ownership of the 799 * underlying memory blocks is retained by the caller, which must guarantee 800 * that they remain valid until the handler is called. 801 * 802 * @param handler The handler to be called when the read operation completes. 803 * Copies will be made of the handler as required. The function signature of 804 * the handler must be: 805 * @code void handler( 806 * const asio::error_code& error, // Result of operation. 807 * std::size_t bytes_transferred // Number of bytes read. 808 * ); @endcode 809 * Regardless of whether the asynchronous operation completes immediately or 810 * not, the handler will not be invoked from within this function. Invocation 811 * of the handler will be performed in a manner equivalent to using 812 * asio::io_service::post(). 813 * 814 * @note The read operation may not read all of the requested number of bytes. 815 * Consider using the @ref async_read function if you need to ensure that the 816 * requested amount of data is read before the asynchronous operation 817 * completes. 818 * 819 * @par Example 820 * To read into a single data buffer use the @ref buffer function as follows: 821 * @code 822 * socket.async_read_some(asio::buffer(data, size), handler); 823 * @endcode 824 * See the @ref buffer documentation for information on reading into multiple 825 * buffers in one go, and how to use it with arrays, boost::array or 826 * std::vector. 827 */ 828 template <typename MutableBufferSequence, typename ReadHandler> ASIO_INITFN_RESULT_TYPE(ReadHandler,void (asio::error_code,std::size_t))829 ASIO_INITFN_RESULT_TYPE(ReadHandler, 830 void (asio::error_code, std::size_t)) 831 async_read_some(const MutableBufferSequence& buffers, 832 ASIO_MOVE_ARG(ReadHandler) handler) 833 { 834 // If you get an error on the following line it means that your handler does 835 // not meet the documented type requirements for a ReadHandler. 836 ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check; 837 838 return this->get_service().async_receive(this->get_implementation(), 839 buffers, 0, ASIO_MOVE_CAST(ReadHandler)(handler)); 840 } 841 }; 842 843 } // namespace asio 844 845 #include "asio/detail/pop_options.hpp" 846 847 #endif // ASIO_BASIC_STREAM_SOCKET_HPP 848