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