Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/asio/basic_socket.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 // | |
2 // basic_socket.hpp | |
3 // ~~~~~~~~~~~~~~~~ | |
4 // | |
5 // Copyright (c) 2003-2013 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_SOCKET_HPP | |
12 #define BOOST_ASIO_BASIC_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 <boost/asio/async_result.hpp> | |
20 #include <boost/asio/basic_io_object.hpp> | |
21 #include <boost/asio/detail/handler_type_requirements.hpp> | |
22 #include <boost/asio/detail/throw_error.hpp> | |
23 #include <boost/asio/detail/type_traits.hpp> | |
24 #include <boost/asio/error.hpp> | |
25 #include <boost/asio/socket_base.hpp> | |
26 | |
27 #include <boost/asio/detail/push_options.hpp> | |
28 | |
29 namespace boost { | |
30 namespace asio { | |
31 | |
32 /// Provides socket functionality. | |
33 /** | |
34 * The basic_socket class template provides functionality that is common to both | |
35 * stream-oriented and datagram-oriented sockets. | |
36 * | |
37 * @par Thread Safety | |
38 * @e Distinct @e objects: Safe.@n | |
39 * @e Shared @e objects: Unsafe. | |
40 */ | |
41 template <typename Protocol, typename SocketService> | |
42 class basic_socket | |
43 : public basic_io_object<SocketService>, | |
44 public socket_base | |
45 { | |
46 public: | |
47 /// (Deprecated: Use native_handle_type.) The native representation of a | |
48 /// socket. | |
49 typedef typename SocketService::native_handle_type native_type; | |
50 | |
51 /// The native representation of a socket. | |
52 typedef typename SocketService::native_handle_type 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 /// A basic_socket is always the lowest layer. | |
61 typedef basic_socket<Protocol, SocketService> lowest_layer_type; | |
62 | |
63 /// Construct a basic_socket without opening it. | |
64 /** | |
65 * This constructor creates a socket without opening it. | |
66 * | |
67 * @param io_service The io_service object that the socket will use to | |
68 * dispatch handlers for any asynchronous operations performed on the socket. | |
69 */ | |
70 explicit basic_socket(boost::asio::io_service& io_service) | |
71 : basic_io_object<SocketService>(io_service) | |
72 { | |
73 } | |
74 | |
75 /// Construct and open a basic_socket. | |
76 /** | |
77 * This constructor creates and opens a socket. | |
78 * | |
79 * @param io_service The io_service object that the socket will use to | |
80 * dispatch handlers for any asynchronous operations performed on the socket. | |
81 * | |
82 * @param protocol An object specifying protocol parameters to be used. | |
83 * | |
84 * @throws boost::system::system_error Thrown on failure. | |
85 */ | |
86 basic_socket(boost::asio::io_service& io_service, | |
87 const protocol_type& protocol) | |
88 : basic_io_object<SocketService>(io_service) | |
89 { | |
90 boost::system::error_code ec; | |
91 this->get_service().open(this->get_implementation(), protocol, ec); | |
92 boost::asio::detail::throw_error(ec, "open"); | |
93 } | |
94 | |
95 /// Construct a basic_socket, opening it and binding it to the given local | |
96 /// endpoint. | |
97 /** | |
98 * This constructor creates a socket and automatically opens it bound to the | |
99 * specified endpoint on the local machine. The protocol used is the protocol | |
100 * associated with the given endpoint. | |
101 * | |
102 * @param io_service The io_service object that the 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 socket will | |
106 * be bound. | |
107 * | |
108 * @throws boost::system::system_error Thrown on failure. | |
109 */ | |
110 basic_socket(boost::asio::io_service& io_service, | |
111 const endpoint_type& endpoint) | |
112 : basic_io_object<SocketService>(io_service) | |
113 { | |
114 boost::system::error_code ec; | |
115 const protocol_type protocol = endpoint.protocol(); | |
116 this->get_service().open(this->get_implementation(), protocol, ec); | |
117 boost::asio::detail::throw_error(ec, "open"); | |
118 this->get_service().bind(this->get_implementation(), endpoint, ec); | |
119 boost::asio::detail::throw_error(ec, "bind"); | |
120 } | |
121 | |
122 /// Construct a basic_socket on an existing native socket. | |
123 /** | |
124 * This constructor creates a socket object to hold an existing native socket. | |
125 * | |
126 * @param io_service The io_service object that the socket will use to | |
127 * dispatch handlers for any asynchronous operations performed on the socket. | |
128 * | |
129 * @param protocol An object specifying protocol parameters to be used. | |
130 * | |
131 * @param native_socket A native socket. | |
132 * | |
133 * @throws boost::system::system_error Thrown on failure. | |
134 */ | |
135 basic_socket(boost::asio::io_service& io_service, | |
136 const protocol_type& protocol, const native_handle_type& native_socket) | |
137 : basic_io_object<SocketService>(io_service) | |
138 { | |
139 boost::system::error_code ec; | |
140 this->get_service().assign(this->get_implementation(), | |
141 protocol, native_socket, ec); | |
142 boost::asio::detail::throw_error(ec, "assign"); | |
143 } | |
144 | |
145 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) | |
146 /// Move-construct a basic_socket from another. | |
147 /** | |
148 * This constructor moves a socket from one object to another. | |
149 * | |
150 * @param other The other basic_socket object from which the move will | |
151 * occur. | |
152 * | |
153 * @note Following the move, the moved-from object is in the same state as if | |
154 * constructed using the @c basic_socket(io_service&) constructor. | |
155 */ | |
156 basic_socket(basic_socket&& other) | |
157 : basic_io_object<SocketService>( | |
158 BOOST_ASIO_MOVE_CAST(basic_socket)(other)) | |
159 { | |
160 } | |
161 | |
162 /// Move-assign a basic_socket from another. | |
163 /** | |
164 * This assignment operator moves a socket from one object to another. | |
165 * | |
166 * @param other The other basic_socket object from which the move will | |
167 * occur. | |
168 * | |
169 * @note Following the move, the moved-from object is in the same state as if | |
170 * constructed using the @c basic_socket(io_service&) constructor. | |
171 */ | |
172 basic_socket& operator=(basic_socket&& other) | |
173 { | |
174 basic_io_object<SocketService>::operator=( | |
175 BOOST_ASIO_MOVE_CAST(basic_socket)(other)); | |
176 return *this; | |
177 } | |
178 | |
179 // All sockets have access to each other's implementations. | |
180 template <typename Protocol1, typename SocketService1> | |
181 friend class basic_socket; | |
182 | |
183 /// Move-construct a basic_socket from a socket of another protocol type. | |
184 /** | |
185 * This constructor moves a socket from one object to another. | |
186 * | |
187 * @param other The other basic_socket object from which the move will | |
188 * occur. | |
189 * | |
190 * @note Following the move, the moved-from object is in the same state as if | |
191 * constructed using the @c basic_socket(io_service&) constructor. | |
192 */ | |
193 template <typename Protocol1, typename SocketService1> | |
194 basic_socket(basic_socket<Protocol1, SocketService1>&& other, | |
195 typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0) | |
196 : basic_io_object<SocketService>(other.get_io_service()) | |
197 { | |
198 this->get_service().template converting_move_construct<Protocol1>( | |
199 this->get_implementation(), other.get_implementation()); | |
200 } | |
201 | |
202 /// Move-assign a basic_socket from a socket of another protocol type. | |
203 /** | |
204 * This assignment operator moves a socket from one object to another. | |
205 * | |
206 * @param other The other basic_socket object from which the move will | |
207 * occur. | |
208 * | |
209 * @note Following the move, the moved-from object is in the same state as if | |
210 * constructed using the @c basic_socket(io_service&) constructor. | |
211 */ | |
212 template <typename Protocol1, typename SocketService1> | |
213 typename enable_if<is_convertible<Protocol1, Protocol>::value, | |
214 basic_socket>::type& operator=( | |
215 basic_socket<Protocol1, SocketService1>&& other) | |
216 { | |
217 basic_socket tmp(BOOST_ASIO_MOVE_CAST2(basic_socket< | |
218 Protocol1, SocketService1>)(other)); | |
219 basic_io_object<SocketService>::operator=( | |
220 BOOST_ASIO_MOVE_CAST(basic_socket)(tmp)); | |
221 return *this; | |
222 } | |
223 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) | |
224 | |
225 /// Get a reference to the lowest layer. | |
226 /** | |
227 * This function returns a reference to the lowest layer in a stack of | |
228 * layers. Since a basic_socket cannot contain any further layers, it simply | |
229 * returns a reference to itself. | |
230 * | |
231 * @return A reference to the lowest layer in the stack of layers. Ownership | |
232 * is not transferred to the caller. | |
233 */ | |
234 lowest_layer_type& lowest_layer() | |
235 { | |
236 return *this; | |
237 } | |
238 | |
239 /// Get a const reference to the lowest layer. | |
240 /** | |
241 * This function returns a const reference to the lowest layer in a stack of | |
242 * layers. Since a basic_socket cannot contain any further layers, it simply | |
243 * returns a reference to itself. | |
244 * | |
245 * @return A const reference to the lowest layer in the stack of layers. | |
246 * Ownership is not transferred to the caller. | |
247 */ | |
248 const lowest_layer_type& lowest_layer() const | |
249 { | |
250 return *this; | |
251 } | |
252 | |
253 /// Open the socket using the specified protocol. | |
254 /** | |
255 * This function opens the socket so that it will use the specified protocol. | |
256 * | |
257 * @param protocol An object specifying protocol parameters to be used. | |
258 * | |
259 * @throws boost::system::system_error Thrown on failure. | |
260 * | |
261 * @par Example | |
262 * @code | |
263 * boost::asio::ip::tcp::socket socket(io_service); | |
264 * socket.open(boost::asio::ip::tcp::v4()); | |
265 * @endcode | |
266 */ | |
267 void open(const protocol_type& protocol = protocol_type()) | |
268 { | |
269 boost::system::error_code ec; | |
270 this->get_service().open(this->get_implementation(), protocol, ec); | |
271 boost::asio::detail::throw_error(ec, "open"); | |
272 } | |
273 | |
274 /// Open the socket using the specified protocol. | |
275 /** | |
276 * This function opens the socket so that it will use the specified protocol. | |
277 * | |
278 * @param protocol An object specifying which protocol is to be used. | |
279 * | |
280 * @param ec Set to indicate what error occurred, if any. | |
281 * | |
282 * @par Example | |
283 * @code | |
284 * boost::asio::ip::tcp::socket socket(io_service); | |
285 * boost::system::error_code ec; | |
286 * socket.open(boost::asio::ip::tcp::v4(), ec); | |
287 * if (ec) | |
288 * { | |
289 * // An error occurred. | |
290 * } | |
291 * @endcode | |
292 */ | |
293 boost::system::error_code open(const protocol_type& protocol, | |
294 boost::system::error_code& ec) | |
295 { | |
296 return this->get_service().open(this->get_implementation(), protocol, ec); | |
297 } | |
298 | |
299 /// Assign an existing native socket to the socket. | |
300 /* | |
301 * This function opens the socket to hold an existing native socket. | |
302 * | |
303 * @param protocol An object specifying which protocol is to be used. | |
304 * | |
305 * @param native_socket A native socket. | |
306 * | |
307 * @throws boost::system::system_error Thrown on failure. | |
308 */ | |
309 void assign(const protocol_type& protocol, | |
310 const native_handle_type& native_socket) | |
311 { | |
312 boost::system::error_code ec; | |
313 this->get_service().assign(this->get_implementation(), | |
314 protocol, native_socket, ec); | |
315 boost::asio::detail::throw_error(ec, "assign"); | |
316 } | |
317 | |
318 /// Assign an existing native socket to the socket. | |
319 /* | |
320 * This function opens the socket to hold an existing native socket. | |
321 * | |
322 * @param protocol An object specifying which protocol is to be used. | |
323 * | |
324 * @param native_socket A native socket. | |
325 * | |
326 * @param ec Set to indicate what error occurred, if any. | |
327 */ | |
328 boost::system::error_code assign(const protocol_type& protocol, | |
329 const native_handle_type& native_socket, boost::system::error_code& ec) | |
330 { | |
331 return this->get_service().assign(this->get_implementation(), | |
332 protocol, native_socket, ec); | |
333 } | |
334 | |
335 /// Determine whether the socket is open. | |
336 bool is_open() const | |
337 { | |
338 return this->get_service().is_open(this->get_implementation()); | |
339 } | |
340 | |
341 /// Close the socket. | |
342 /** | |
343 * This function is used to close the socket. Any asynchronous send, receive | |
344 * or connect operations will be cancelled immediately, and will complete | |
345 * with the boost::asio::error::operation_aborted error. | |
346 * | |
347 * @throws boost::system::system_error Thrown on failure. Note that, even if | |
348 * the function indicates an error, the underlying descriptor is closed. | |
349 * | |
350 * @note For portable behaviour with respect to graceful closure of a | |
351 * connected socket, call shutdown() before closing the socket. | |
352 */ | |
353 void close() | |
354 { | |
355 boost::system::error_code ec; | |
356 this->get_service().close(this->get_implementation(), ec); | |
357 boost::asio::detail::throw_error(ec, "close"); | |
358 } | |
359 | |
360 /// Close the socket. | |
361 /** | |
362 * This function is used to close the socket. Any asynchronous send, receive | |
363 * or connect operations will be cancelled immediately, and will complete | |
364 * with the boost::asio::error::operation_aborted error. | |
365 * | |
366 * @param ec Set to indicate what error occurred, if any. Note that, even if | |
367 * the function indicates an error, the underlying descriptor is closed. | |
368 * | |
369 * @par Example | |
370 * @code | |
371 * boost::asio::ip::tcp::socket socket(io_service); | |
372 * ... | |
373 * boost::system::error_code ec; | |
374 * socket.close(ec); | |
375 * if (ec) | |
376 * { | |
377 * // An error occurred. | |
378 * } | |
379 * @endcode | |
380 * | |
381 * @note For portable behaviour with respect to graceful closure of a | |
382 * connected socket, call shutdown() before closing the socket. | |
383 */ | |
384 boost::system::error_code close(boost::system::error_code& ec) | |
385 { | |
386 return this->get_service().close(this->get_implementation(), ec); | |
387 } | |
388 | |
389 /// (Deprecated: Use native_handle().) Get the native socket representation. | |
390 /** | |
391 * This function may be used to obtain the underlying representation of the | |
392 * socket. This is intended to allow access to native socket functionality | |
393 * that is not otherwise provided. | |
394 */ | |
395 native_type native() | |
396 { | |
397 return this->get_service().native_handle(this->get_implementation()); | |
398 } | |
399 | |
400 /// Get the native socket representation. | |
401 /** | |
402 * This function may be used to obtain the underlying representation of the | |
403 * socket. This is intended to allow access to native socket functionality | |
404 * that is not otherwise provided. | |
405 */ | |
406 native_handle_type native_handle() | |
407 { | |
408 return this->get_service().native_handle(this->get_implementation()); | |
409 } | |
410 | |
411 /// Cancel all asynchronous operations associated with the socket. | |
412 /** | |
413 * This function causes all outstanding asynchronous connect, send and receive | |
414 * operations to finish immediately, and the handlers for cancelled operations | |
415 * will be passed the boost::asio::error::operation_aborted error. | |
416 * | |
417 * @throws boost::system::system_error Thrown on failure. | |
418 * | |
419 * @note Calls to cancel() will always fail with | |
420 * boost::asio::error::operation_not_supported when run on Windows XP, Windows | |
421 * Server 2003, and earlier versions of Windows, unless | |
422 * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has | |
423 * two issues that should be considered before enabling its use: | |
424 * | |
425 * @li It will only cancel asynchronous operations that were initiated in the | |
426 * current thread. | |
427 * | |
428 * @li It can appear to complete without error, but the request to cancel the | |
429 * unfinished operations may be silently ignored by the operating system. | |
430 * Whether it works or not seems to depend on the drivers that are installed. | |
431 * | |
432 * For portable cancellation, consider using one of the following | |
433 * alternatives: | |
434 * | |
435 * @li Disable asio's I/O completion port backend by defining | |
436 * BOOST_ASIO_DISABLE_IOCP. | |
437 * | |
438 * @li Use the close() function to simultaneously cancel the outstanding | |
439 * operations and close the socket. | |
440 * | |
441 * When running on Windows Vista, Windows Server 2008, and later, the | |
442 * CancelIoEx function is always used. This function does not have the | |
443 * problems described above. | |
444 */ | |
445 #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ | |
446 && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ | |
447 && !defined(BOOST_ASIO_ENABLE_CANCELIO) | |
448 __declspec(deprecated("By default, this function always fails with " | |
449 "operation_not_supported when used on Windows XP, Windows Server 2003, " | |
450 "or earlier. Consult documentation for details.")) | |
451 #endif | |
452 void cancel() | |
453 { | |
454 boost::system::error_code ec; | |
455 this->get_service().cancel(this->get_implementation(), ec); | |
456 boost::asio::detail::throw_error(ec, "cancel"); | |
457 } | |
458 | |
459 /// Cancel all asynchronous operations associated with the socket. | |
460 /** | |
461 * This function causes all outstanding asynchronous connect, send and receive | |
462 * operations to finish immediately, and the handlers for cancelled operations | |
463 * will be passed the boost::asio::error::operation_aborted error. | |
464 * | |
465 * @param ec Set to indicate what error occurred, if any. | |
466 * | |
467 * @note Calls to cancel() will always fail with | |
468 * boost::asio::error::operation_not_supported when run on Windows XP, Windows | |
469 * Server 2003, and earlier versions of Windows, unless | |
470 * BOOST_ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has | |
471 * two issues that should be considered before enabling its use: | |
472 * | |
473 * @li It will only cancel asynchronous operations that were initiated in the | |
474 * current thread. | |
475 * | |
476 * @li It can appear to complete without error, but the request to cancel the | |
477 * unfinished operations may be silently ignored by the operating system. | |
478 * Whether it works or not seems to depend on the drivers that are installed. | |
479 * | |
480 * For portable cancellation, consider using one of the following | |
481 * alternatives: | |
482 * | |
483 * @li Disable asio's I/O completion port backend by defining | |
484 * BOOST_ASIO_DISABLE_IOCP. | |
485 * | |
486 * @li Use the close() function to simultaneously cancel the outstanding | |
487 * operations and close the socket. | |
488 * | |
489 * When running on Windows Vista, Windows Server 2008, and later, the | |
490 * CancelIoEx function is always used. This function does not have the | |
491 * problems described above. | |
492 */ | |
493 #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC >= 1400) \ | |
494 && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \ | |
495 && !defined(BOOST_ASIO_ENABLE_CANCELIO) | |
496 __declspec(deprecated("By default, this function always fails with " | |
497 "operation_not_supported when used on Windows XP, Windows Server 2003, " | |
498 "or earlier. Consult documentation for details.")) | |
499 #endif | |
500 boost::system::error_code cancel(boost::system::error_code& ec) | |
501 { | |
502 return this->get_service().cancel(this->get_implementation(), ec); | |
503 } | |
504 | |
505 /// Determine whether the socket is at the out-of-band data mark. | |
506 /** | |
507 * This function is used to check whether the socket input is currently | |
508 * positioned at the out-of-band data mark. | |
509 * | |
510 * @return A bool indicating whether the socket is at the out-of-band data | |
511 * mark. | |
512 * | |
513 * @throws boost::system::system_error Thrown on failure. | |
514 */ | |
515 bool at_mark() const | |
516 { | |
517 boost::system::error_code ec; | |
518 bool b = this->get_service().at_mark(this->get_implementation(), ec); | |
519 boost::asio::detail::throw_error(ec, "at_mark"); | |
520 return b; | |
521 } | |
522 | |
523 /// Determine whether the socket is at the out-of-band data mark. | |
524 /** | |
525 * This function is used to check whether the socket input is currently | |
526 * positioned at the out-of-band data mark. | |
527 * | |
528 * @param ec Set to indicate what error occurred, if any. | |
529 * | |
530 * @return A bool indicating whether the socket is at the out-of-band data | |
531 * mark. | |
532 */ | |
533 bool at_mark(boost::system::error_code& ec) const | |
534 { | |
535 return this->get_service().at_mark(this->get_implementation(), ec); | |
536 } | |
537 | |
538 /// Determine the number of bytes available for reading. | |
539 /** | |
540 * This function is used to determine the number of bytes that may be read | |
541 * without blocking. | |
542 * | |
543 * @return The number of bytes that may be read without blocking, or 0 if an | |
544 * error occurs. | |
545 * | |
546 * @throws boost::system::system_error Thrown on failure. | |
547 */ | |
548 std::size_t available() const | |
549 { | |
550 boost::system::error_code ec; | |
551 std::size_t s = this->get_service().available( | |
552 this->get_implementation(), ec); | |
553 boost::asio::detail::throw_error(ec, "available"); | |
554 return s; | |
555 } | |
556 | |
557 /// Determine the number of bytes available for reading. | |
558 /** | |
559 * This function is used to determine the number of bytes that may be read | |
560 * without blocking. | |
561 * | |
562 * @param ec Set to indicate what error occurred, if any. | |
563 * | |
564 * @return The number of bytes that may be read without blocking, or 0 if an | |
565 * error occurs. | |
566 */ | |
567 std::size_t available(boost::system::error_code& ec) const | |
568 { | |
569 return this->get_service().available(this->get_implementation(), ec); | |
570 } | |
571 | |
572 /// Bind the socket to the given local endpoint. | |
573 /** | |
574 * This function binds the socket to the specified endpoint on the local | |
575 * machine. | |
576 * | |
577 * @param endpoint An endpoint on the local machine to which the socket will | |
578 * be bound. | |
579 * | |
580 * @throws boost::system::system_error Thrown on failure. | |
581 * | |
582 * @par Example | |
583 * @code | |
584 * boost::asio::ip::tcp::socket socket(io_service); | |
585 * socket.open(boost::asio::ip::tcp::v4()); | |
586 * socket.bind(boost::asio::ip::tcp::endpoint( | |
587 * boost::asio::ip::tcp::v4(), 12345)); | |
588 * @endcode | |
589 */ | |
590 void bind(const endpoint_type& endpoint) | |
591 { | |
592 boost::system::error_code ec; | |
593 this->get_service().bind(this->get_implementation(), endpoint, ec); | |
594 boost::asio::detail::throw_error(ec, "bind"); | |
595 } | |
596 | |
597 /// Bind the socket to the given local endpoint. | |
598 /** | |
599 * This function binds the socket to the specified endpoint on the local | |
600 * machine. | |
601 * | |
602 * @param endpoint An endpoint on the local machine to which the socket will | |
603 * be bound. | |
604 * | |
605 * @param ec Set to indicate what error occurred, if any. | |
606 * | |
607 * @par Example | |
608 * @code | |
609 * boost::asio::ip::tcp::socket socket(io_service); | |
610 * socket.open(boost::asio::ip::tcp::v4()); | |
611 * boost::system::error_code ec; | |
612 * socket.bind(boost::asio::ip::tcp::endpoint( | |
613 * boost::asio::ip::tcp::v4(), 12345), ec); | |
614 * if (ec) | |
615 * { | |
616 * // An error occurred. | |
617 * } | |
618 * @endcode | |
619 */ | |
620 boost::system::error_code bind(const endpoint_type& endpoint, | |
621 boost::system::error_code& ec) | |
622 { | |
623 return this->get_service().bind(this->get_implementation(), endpoint, ec); | |
624 } | |
625 | |
626 /// Connect the socket to the specified endpoint. | |
627 /** | |
628 * This function is used to connect a socket to the specified remote endpoint. | |
629 * The function call will block until the connection is successfully made or | |
630 * an error occurs. | |
631 * | |
632 * The socket is automatically opened if it is not already open. If the | |
633 * connect fails, and the socket was automatically opened, the socket is | |
634 * not returned to the closed state. | |
635 * | |
636 * @param peer_endpoint The remote endpoint to which the socket will be | |
637 * connected. | |
638 * | |
639 * @throws boost::system::system_error Thrown on failure. | |
640 * | |
641 * @par Example | |
642 * @code | |
643 * boost::asio::ip::tcp::socket socket(io_service); | |
644 * boost::asio::ip::tcp::endpoint endpoint( | |
645 * boost::asio::ip::address::from_string("1.2.3.4"), 12345); | |
646 * socket.connect(endpoint); | |
647 * @endcode | |
648 */ | |
649 void connect(const endpoint_type& peer_endpoint) | |
650 { | |
651 boost::system::error_code ec; | |
652 if (!is_open()) | |
653 { | |
654 this->get_service().open(this->get_implementation(), | |
655 peer_endpoint.protocol(), ec); | |
656 boost::asio::detail::throw_error(ec, "connect"); | |
657 } | |
658 this->get_service().connect(this->get_implementation(), peer_endpoint, ec); | |
659 boost::asio::detail::throw_error(ec, "connect"); | |
660 } | |
661 | |
662 /// Connect the socket to the specified endpoint. | |
663 /** | |
664 * This function is used to connect a socket to the specified remote endpoint. | |
665 * The function call will block until the connection is successfully made or | |
666 * an error occurs. | |
667 * | |
668 * The socket is automatically opened if it is not already open. If the | |
669 * connect fails, and the socket was automatically opened, the socket is | |
670 * not returned to the closed state. | |
671 * | |
672 * @param peer_endpoint The remote endpoint to which the socket will be | |
673 * connected. | |
674 * | |
675 * @param ec Set to indicate what error occurred, if any. | |
676 * | |
677 * @par Example | |
678 * @code | |
679 * boost::asio::ip::tcp::socket socket(io_service); | |
680 * boost::asio::ip::tcp::endpoint endpoint( | |
681 * boost::asio::ip::address::from_string("1.2.3.4"), 12345); | |
682 * boost::system::error_code ec; | |
683 * socket.connect(endpoint, ec); | |
684 * if (ec) | |
685 * { | |
686 * // An error occurred. | |
687 * } | |
688 * @endcode | |
689 */ | |
690 boost::system::error_code connect(const endpoint_type& peer_endpoint, | |
691 boost::system::error_code& ec) | |
692 { | |
693 if (!is_open()) | |
694 { | |
695 if (this->get_service().open(this->get_implementation(), | |
696 peer_endpoint.protocol(), ec)) | |
697 { | |
698 return ec; | |
699 } | |
700 } | |
701 | |
702 return this->get_service().connect( | |
703 this->get_implementation(), peer_endpoint, ec); | |
704 } | |
705 | |
706 /// Start an asynchronous connect. | |
707 /** | |
708 * This function is used to asynchronously connect a socket to the specified | |
709 * remote endpoint. The function call always returns immediately. | |
710 * | |
711 * The socket is automatically opened if it is not already open. If the | |
712 * connect fails, and the socket was automatically opened, the socket is | |
713 * not returned to the closed state. | |
714 * | |
715 * @param peer_endpoint The remote endpoint to which the socket will be | |
716 * connected. Copies will be made of the endpoint object as required. | |
717 * | |
718 * @param handler The handler to be called when the connection operation | |
719 * completes. Copies will be made of the handler as required. The function | |
720 * signature of the handler must be: | |
721 * @code void handler( | |
722 * const boost::system::error_code& error // Result of operation | |
723 * ); @endcode | |
724 * Regardless of whether the asynchronous operation completes immediately or | |
725 * not, the handler will not be invoked from within this function. Invocation | |
726 * of the handler will be performed in a manner equivalent to using | |
727 * boost::asio::io_service::post(). | |
728 * | |
729 * @par Example | |
730 * @code | |
731 * void connect_handler(const boost::system::error_code& error) | |
732 * { | |
733 * if (!error) | |
734 * { | |
735 * // Connect succeeded. | |
736 * } | |
737 * } | |
738 * | |
739 * ... | |
740 * | |
741 * boost::asio::ip::tcp::socket socket(io_service); | |
742 * boost::asio::ip::tcp::endpoint endpoint( | |
743 * boost::asio::ip::address::from_string("1.2.3.4"), 12345); | |
744 * socket.async_connect(endpoint, connect_handler); | |
745 * @endcode | |
746 */ | |
747 template <typename ConnectHandler> | |
748 BOOST_ASIO_INITFN_RESULT_TYPE(ConnectHandler, | |
749 void (boost::system::error_code)) | |
750 async_connect(const endpoint_type& peer_endpoint, | |
751 BOOST_ASIO_MOVE_ARG(ConnectHandler) handler) | |
752 { | |
753 // If you get an error on the following line it means that your handler does | |
754 // not meet the documented type requirements for a ConnectHandler. | |
755 BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check; | |
756 | |
757 if (!is_open()) | |
758 { | |
759 boost::system::error_code ec; | |
760 const protocol_type protocol = peer_endpoint.protocol(); | |
761 if (this->get_service().open(this->get_implementation(), protocol, ec)) | |
762 { | |
763 detail::async_result_init< | |
764 ConnectHandler, void (boost::system::error_code)> init( | |
765 BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler)); | |
766 | |
767 this->get_io_service().post( | |
768 boost::asio::detail::bind_handler( | |
769 BOOST_ASIO_MOVE_CAST(BOOST_ASIO_HANDLER_TYPE( | |
770 ConnectHandler, void (boost::system::error_code)))( | |
771 init.handler), ec)); | |
772 | |
773 return init.result.get(); | |
774 } | |
775 } | |
776 | |
777 return this->get_service().async_connect(this->get_implementation(), | |
778 peer_endpoint, BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler)); | |
779 } | |
780 | |
781 /// Set an option on the socket. | |
782 /** | |
783 * This function is used to set an option on the socket. | |
784 * | |
785 * @param option The new option value to be set on the socket. | |
786 * | |
787 * @throws boost::system::system_error Thrown on failure. | |
788 * | |
789 * @sa SettableSocketOption @n | |
790 * boost::asio::socket_base::broadcast @n | |
791 * boost::asio::socket_base::do_not_route @n | |
792 * boost::asio::socket_base::keep_alive @n | |
793 * boost::asio::socket_base::linger @n | |
794 * boost::asio::socket_base::receive_buffer_size @n | |
795 * boost::asio::socket_base::receive_low_watermark @n | |
796 * boost::asio::socket_base::reuse_address @n | |
797 * boost::asio::socket_base::send_buffer_size @n | |
798 * boost::asio::socket_base::send_low_watermark @n | |
799 * boost::asio::ip::multicast::join_group @n | |
800 * boost::asio::ip::multicast::leave_group @n | |
801 * boost::asio::ip::multicast::enable_loopback @n | |
802 * boost::asio::ip::multicast::outbound_interface @n | |
803 * boost::asio::ip::multicast::hops @n | |
804 * boost::asio::ip::tcp::no_delay | |
805 * | |
806 * @par Example | |
807 * Setting the IPPROTO_TCP/TCP_NODELAY option: | |
808 * @code | |
809 * boost::asio::ip::tcp::socket socket(io_service); | |
810 * ... | |
811 * boost::asio::ip::tcp::no_delay option(true); | |
812 * socket.set_option(option); | |
813 * @endcode | |
814 */ | |
815 template <typename SettableSocketOption> | |
816 void set_option(const SettableSocketOption& option) | |
817 { | |
818 boost::system::error_code ec; | |
819 this->get_service().set_option(this->get_implementation(), option, ec); | |
820 boost::asio::detail::throw_error(ec, "set_option"); | |
821 } | |
822 | |
823 /// Set an option on the socket. | |
824 /** | |
825 * This function is used to set an option on the socket. | |
826 * | |
827 * @param option The new option value to be set on the socket. | |
828 * | |
829 * @param ec Set to indicate what error occurred, if any. | |
830 * | |
831 * @sa SettableSocketOption @n | |
832 * boost::asio::socket_base::broadcast @n | |
833 * boost::asio::socket_base::do_not_route @n | |
834 * boost::asio::socket_base::keep_alive @n | |
835 * boost::asio::socket_base::linger @n | |
836 * boost::asio::socket_base::receive_buffer_size @n | |
837 * boost::asio::socket_base::receive_low_watermark @n | |
838 * boost::asio::socket_base::reuse_address @n | |
839 * boost::asio::socket_base::send_buffer_size @n | |
840 * boost::asio::socket_base::send_low_watermark @n | |
841 * boost::asio::ip::multicast::join_group @n | |
842 * boost::asio::ip::multicast::leave_group @n | |
843 * boost::asio::ip::multicast::enable_loopback @n | |
844 * boost::asio::ip::multicast::outbound_interface @n | |
845 * boost::asio::ip::multicast::hops @n | |
846 * boost::asio::ip::tcp::no_delay | |
847 * | |
848 * @par Example | |
849 * Setting the IPPROTO_TCP/TCP_NODELAY option: | |
850 * @code | |
851 * boost::asio::ip::tcp::socket socket(io_service); | |
852 * ... | |
853 * boost::asio::ip::tcp::no_delay option(true); | |
854 * boost::system::error_code ec; | |
855 * socket.set_option(option, ec); | |
856 * if (ec) | |
857 * { | |
858 * // An error occurred. | |
859 * } | |
860 * @endcode | |
861 */ | |
862 template <typename SettableSocketOption> | |
863 boost::system::error_code set_option(const SettableSocketOption& option, | |
864 boost::system::error_code& ec) | |
865 { | |
866 return this->get_service().set_option( | |
867 this->get_implementation(), option, ec); | |
868 } | |
869 | |
870 /// Get an option from the socket. | |
871 /** | |
872 * This function is used to get the current value of an option on the socket. | |
873 * | |
874 * @param option The option value to be obtained from the socket. | |
875 * | |
876 * @throws boost::system::system_error Thrown on failure. | |
877 * | |
878 * @sa GettableSocketOption @n | |
879 * boost::asio::socket_base::broadcast @n | |
880 * boost::asio::socket_base::do_not_route @n | |
881 * boost::asio::socket_base::keep_alive @n | |
882 * boost::asio::socket_base::linger @n | |
883 * boost::asio::socket_base::receive_buffer_size @n | |
884 * boost::asio::socket_base::receive_low_watermark @n | |
885 * boost::asio::socket_base::reuse_address @n | |
886 * boost::asio::socket_base::send_buffer_size @n | |
887 * boost::asio::socket_base::send_low_watermark @n | |
888 * boost::asio::ip::multicast::join_group @n | |
889 * boost::asio::ip::multicast::leave_group @n | |
890 * boost::asio::ip::multicast::enable_loopback @n | |
891 * boost::asio::ip::multicast::outbound_interface @n | |
892 * boost::asio::ip::multicast::hops @n | |
893 * boost::asio::ip::tcp::no_delay | |
894 * | |
895 * @par Example | |
896 * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: | |
897 * @code | |
898 * boost::asio::ip::tcp::socket socket(io_service); | |
899 * ... | |
900 * boost::asio::ip::tcp::socket::keep_alive option; | |
901 * socket.get_option(option); | |
902 * bool is_set = option.value(); | |
903 * @endcode | |
904 */ | |
905 template <typename GettableSocketOption> | |
906 void get_option(GettableSocketOption& option) const | |
907 { | |
908 boost::system::error_code ec; | |
909 this->get_service().get_option(this->get_implementation(), option, ec); | |
910 boost::asio::detail::throw_error(ec, "get_option"); | |
911 } | |
912 | |
913 /// Get an option from the socket. | |
914 /** | |
915 * This function is used to get the current value of an option on the socket. | |
916 * | |
917 * @param option The option value to be obtained from the socket. | |
918 * | |
919 * @param ec Set to indicate what error occurred, if any. | |
920 * | |
921 * @sa GettableSocketOption @n | |
922 * boost::asio::socket_base::broadcast @n | |
923 * boost::asio::socket_base::do_not_route @n | |
924 * boost::asio::socket_base::keep_alive @n | |
925 * boost::asio::socket_base::linger @n | |
926 * boost::asio::socket_base::receive_buffer_size @n | |
927 * boost::asio::socket_base::receive_low_watermark @n | |
928 * boost::asio::socket_base::reuse_address @n | |
929 * boost::asio::socket_base::send_buffer_size @n | |
930 * boost::asio::socket_base::send_low_watermark @n | |
931 * boost::asio::ip::multicast::join_group @n | |
932 * boost::asio::ip::multicast::leave_group @n | |
933 * boost::asio::ip::multicast::enable_loopback @n | |
934 * boost::asio::ip::multicast::outbound_interface @n | |
935 * boost::asio::ip::multicast::hops @n | |
936 * boost::asio::ip::tcp::no_delay | |
937 * | |
938 * @par Example | |
939 * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: | |
940 * @code | |
941 * boost::asio::ip::tcp::socket socket(io_service); | |
942 * ... | |
943 * boost::asio::ip::tcp::socket::keep_alive option; | |
944 * boost::system::error_code ec; | |
945 * socket.get_option(option, ec); | |
946 * if (ec) | |
947 * { | |
948 * // An error occurred. | |
949 * } | |
950 * bool is_set = option.value(); | |
951 * @endcode | |
952 */ | |
953 template <typename GettableSocketOption> | |
954 boost::system::error_code get_option(GettableSocketOption& option, | |
955 boost::system::error_code& ec) const | |
956 { | |
957 return this->get_service().get_option( | |
958 this->get_implementation(), option, ec); | |
959 } | |
960 | |
961 /// Perform an IO control command on the socket. | |
962 /** | |
963 * This function is used to execute an IO control command on the socket. | |
964 * | |
965 * @param command The IO control command to be performed on the socket. | |
966 * | |
967 * @throws boost::system::system_error Thrown on failure. | |
968 * | |
969 * @sa IoControlCommand @n | |
970 * boost::asio::socket_base::bytes_readable @n | |
971 * boost::asio::socket_base::non_blocking_io | |
972 * | |
973 * @par Example | |
974 * Getting the number of bytes ready to read: | |
975 * @code | |
976 * boost::asio::ip::tcp::socket socket(io_service); | |
977 * ... | |
978 * boost::asio::ip::tcp::socket::bytes_readable command; | |
979 * socket.io_control(command); | |
980 * std::size_t bytes_readable = command.get(); | |
981 * @endcode | |
982 */ | |
983 template <typename IoControlCommand> | |
984 void io_control(IoControlCommand& command) | |
985 { | |
986 boost::system::error_code ec; | |
987 this->get_service().io_control(this->get_implementation(), command, ec); | |
988 boost::asio::detail::throw_error(ec, "io_control"); | |
989 } | |
990 | |
991 /// Perform an IO control command on the socket. | |
992 /** | |
993 * This function is used to execute an IO control command on the socket. | |
994 * | |
995 * @param command The IO control command to be performed on the socket. | |
996 * | |
997 * @param ec Set to indicate what error occurred, if any. | |
998 * | |
999 * @sa IoControlCommand @n | |
1000 * boost::asio::socket_base::bytes_readable @n | |
1001 * boost::asio::socket_base::non_blocking_io | |
1002 * | |
1003 * @par Example | |
1004 * Getting the number of bytes ready to read: | |
1005 * @code | |
1006 * boost::asio::ip::tcp::socket socket(io_service); | |
1007 * ... | |
1008 * boost::asio::ip::tcp::socket::bytes_readable command; | |
1009 * boost::system::error_code ec; | |
1010 * socket.io_control(command, ec); | |
1011 * if (ec) | |
1012 * { | |
1013 * // An error occurred. | |
1014 * } | |
1015 * std::size_t bytes_readable = command.get(); | |
1016 * @endcode | |
1017 */ | |
1018 template <typename IoControlCommand> | |
1019 boost::system::error_code io_control(IoControlCommand& command, | |
1020 boost::system::error_code& ec) | |
1021 { | |
1022 return this->get_service().io_control( | |
1023 this->get_implementation(), command, ec); | |
1024 } | |
1025 | |
1026 /// Gets the non-blocking mode of the socket. | |
1027 /** | |
1028 * @returns @c true if the socket's synchronous operations will fail with | |
1029 * boost::asio::error::would_block if they are unable to perform the requested | |
1030 * operation immediately. If @c false, synchronous operations will block | |
1031 * until complete. | |
1032 * | |
1033 * @note The non-blocking mode has no effect on the behaviour of asynchronous | |
1034 * operations. Asynchronous operations will never fail with the error | |
1035 * boost::asio::error::would_block. | |
1036 */ | |
1037 bool non_blocking() const | |
1038 { | |
1039 return this->get_service().non_blocking(this->get_implementation()); | |
1040 } | |
1041 | |
1042 /// Sets the non-blocking mode of the socket. | |
1043 /** | |
1044 * @param mode If @c true, the socket's synchronous operations will fail with | |
1045 * boost::asio::error::would_block if they are unable to perform the requested | |
1046 * operation immediately. If @c false, synchronous operations will block | |
1047 * until complete. | |
1048 * | |
1049 * @throws boost::system::system_error Thrown on failure. | |
1050 * | |
1051 * @note The non-blocking mode has no effect on the behaviour of asynchronous | |
1052 * operations. Asynchronous operations will never fail with the error | |
1053 * boost::asio::error::would_block. | |
1054 */ | |
1055 void non_blocking(bool mode) | |
1056 { | |
1057 boost::system::error_code ec; | |
1058 this->get_service().non_blocking(this->get_implementation(), mode, ec); | |
1059 boost::asio::detail::throw_error(ec, "non_blocking"); | |
1060 } | |
1061 | |
1062 /// Sets the non-blocking mode of the socket. | |
1063 /** | |
1064 * @param mode If @c true, the socket's synchronous operations will fail with | |
1065 * boost::asio::error::would_block if they are unable to perform the requested | |
1066 * operation immediately. If @c false, synchronous operations will block | |
1067 * until complete. | |
1068 * | |
1069 * @param ec Set to indicate what error occurred, if any. | |
1070 * | |
1071 * @note The non-blocking mode has no effect on the behaviour of asynchronous | |
1072 * operations. Asynchronous operations will never fail with the error | |
1073 * boost::asio::error::would_block. | |
1074 */ | |
1075 boost::system::error_code non_blocking( | |
1076 bool mode, boost::system::error_code& ec) | |
1077 { | |
1078 return this->get_service().non_blocking( | |
1079 this->get_implementation(), mode, ec); | |
1080 } | |
1081 | |
1082 /// Gets the non-blocking mode of the native socket implementation. | |
1083 /** | |
1084 * This function is used to retrieve the non-blocking mode of the underlying | |
1085 * native socket. This mode has no effect on the behaviour of the socket | |
1086 * object's synchronous operations. | |
1087 * | |
1088 * @returns @c true if the underlying socket is in non-blocking mode and | |
1089 * direct system calls may fail with boost::asio::error::would_block (or the | |
1090 * equivalent system error). | |
1091 * | |
1092 * @note The current non-blocking mode is cached by the socket object. | |
1093 * Consequently, the return value may be incorrect if the non-blocking mode | |
1094 * was set directly on the native socket. | |
1095 * | |
1096 * @par Example | |
1097 * This function is intended to allow the encapsulation of arbitrary | |
1098 * non-blocking system calls as asynchronous operations, in a way that is | |
1099 * transparent to the user of the socket object. The following example | |
1100 * illustrates how Linux's @c sendfile system call might be encapsulated: | |
1101 * @code template <typename Handler> | |
1102 * struct sendfile_op | |
1103 * { | |
1104 * tcp::socket& sock_; | |
1105 * int fd_; | |
1106 * Handler handler_; | |
1107 * off_t offset_; | |
1108 * std::size_t total_bytes_transferred_; | |
1109 * | |
1110 * // Function call operator meeting WriteHandler requirements. | |
1111 * // Used as the handler for the async_write_some operation. | |
1112 * void operator()(boost::system::error_code ec, std::size_t) | |
1113 * { | |
1114 * // Put the underlying socket into non-blocking mode. | |
1115 * if (!ec) | |
1116 * if (!sock_.native_non_blocking()) | |
1117 * sock_.native_non_blocking(true, ec); | |
1118 * | |
1119 * if (!ec) | |
1120 * { | |
1121 * for (;;) | |
1122 * { | |
1123 * // Try the system call. | |
1124 * errno = 0; | |
1125 * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); | |
1126 * ec = boost::system::error_code(n < 0 ? errno : 0, | |
1127 * boost::asio::error::get_system_category()); | |
1128 * total_bytes_transferred_ += ec ? 0 : n; | |
1129 * | |
1130 * // Retry operation immediately if interrupted by signal. | |
1131 * if (ec == boost::asio::error::interrupted) | |
1132 * continue; | |
1133 * | |
1134 * // Check if we need to run the operation again. | |
1135 * if (ec == boost::asio::error::would_block | |
1136 * || ec == boost::asio::error::try_again) | |
1137 * { | |
1138 * // We have to wait for the socket to become ready again. | |
1139 * sock_.async_write_some(boost::asio::null_buffers(), *this); | |
1140 * return; | |
1141 * } | |
1142 * | |
1143 * if (ec || n == 0) | |
1144 * { | |
1145 * // An error occurred, or we have reached the end of the file. | |
1146 * // Either way we must exit the loop so we can call the handler. | |
1147 * break; | |
1148 * } | |
1149 * | |
1150 * // Loop around to try calling sendfile again. | |
1151 * } | |
1152 * } | |
1153 * | |
1154 * // Pass result back to user's handler. | |
1155 * handler_(ec, total_bytes_transferred_); | |
1156 * } | |
1157 * }; | |
1158 * | |
1159 * template <typename Handler> | |
1160 * void async_sendfile(tcp::socket& sock, int fd, Handler h) | |
1161 * { | |
1162 * sendfile_op<Handler> op = { sock, fd, h, 0, 0 }; | |
1163 * sock.async_write_some(boost::asio::null_buffers(), op); | |
1164 * } @endcode | |
1165 */ | |
1166 bool native_non_blocking() const | |
1167 { | |
1168 return this->get_service().native_non_blocking(this->get_implementation()); | |
1169 } | |
1170 | |
1171 /// Sets the non-blocking mode of the native socket implementation. | |
1172 /** | |
1173 * This function is used to modify the non-blocking mode of the underlying | |
1174 * native socket. It has no effect on the behaviour of the socket object's | |
1175 * synchronous operations. | |
1176 * | |
1177 * @param mode If @c true, the underlying socket is put into non-blocking | |
1178 * mode and direct system calls may fail with boost::asio::error::would_block | |
1179 * (or the equivalent system error). | |
1180 * | |
1181 * @throws boost::system::system_error Thrown on failure. If the @c mode is | |
1182 * @c false, but the current value of @c non_blocking() is @c true, this | |
1183 * function fails with boost::asio::error::invalid_argument, as the | |
1184 * combination does not make sense. | |
1185 * | |
1186 * @par Example | |
1187 * This function is intended to allow the encapsulation of arbitrary | |
1188 * non-blocking system calls as asynchronous operations, in a way that is | |
1189 * transparent to the user of the socket object. The following example | |
1190 * illustrates how Linux's @c sendfile system call might be encapsulated: | |
1191 * @code template <typename Handler> | |
1192 * struct sendfile_op | |
1193 * { | |
1194 * tcp::socket& sock_; | |
1195 * int fd_; | |
1196 * Handler handler_; | |
1197 * off_t offset_; | |
1198 * std::size_t total_bytes_transferred_; | |
1199 * | |
1200 * // Function call operator meeting WriteHandler requirements. | |
1201 * // Used as the handler for the async_write_some operation. | |
1202 * void operator()(boost::system::error_code ec, std::size_t) | |
1203 * { | |
1204 * // Put the underlying socket into non-blocking mode. | |
1205 * if (!ec) | |
1206 * if (!sock_.native_non_blocking()) | |
1207 * sock_.native_non_blocking(true, ec); | |
1208 * | |
1209 * if (!ec) | |
1210 * { | |
1211 * for (;;) | |
1212 * { | |
1213 * // Try the system call. | |
1214 * errno = 0; | |
1215 * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); | |
1216 * ec = boost::system::error_code(n < 0 ? errno : 0, | |
1217 * boost::asio::error::get_system_category()); | |
1218 * total_bytes_transferred_ += ec ? 0 : n; | |
1219 * | |
1220 * // Retry operation immediately if interrupted by signal. | |
1221 * if (ec == boost::asio::error::interrupted) | |
1222 * continue; | |
1223 * | |
1224 * // Check if we need to run the operation again. | |
1225 * if (ec == boost::asio::error::would_block | |
1226 * || ec == boost::asio::error::try_again) | |
1227 * { | |
1228 * // We have to wait for the socket to become ready again. | |
1229 * sock_.async_write_some(boost::asio::null_buffers(), *this); | |
1230 * return; | |
1231 * } | |
1232 * | |
1233 * if (ec || n == 0) | |
1234 * { | |
1235 * // An error occurred, or we have reached the end of the file. | |
1236 * // Either way we must exit the loop so we can call the handler. | |
1237 * break; | |
1238 * } | |
1239 * | |
1240 * // Loop around to try calling sendfile again. | |
1241 * } | |
1242 * } | |
1243 * | |
1244 * // Pass result back to user's handler. | |
1245 * handler_(ec, total_bytes_transferred_); | |
1246 * } | |
1247 * }; | |
1248 * | |
1249 * template <typename Handler> | |
1250 * void async_sendfile(tcp::socket& sock, int fd, Handler h) | |
1251 * { | |
1252 * sendfile_op<Handler> op = { sock, fd, h, 0, 0 }; | |
1253 * sock.async_write_some(boost::asio::null_buffers(), op); | |
1254 * } @endcode | |
1255 */ | |
1256 void native_non_blocking(bool mode) | |
1257 { | |
1258 boost::system::error_code ec; | |
1259 this->get_service().native_non_blocking( | |
1260 this->get_implementation(), mode, ec); | |
1261 boost::asio::detail::throw_error(ec, "native_non_blocking"); | |
1262 } | |
1263 | |
1264 /// Sets the non-blocking mode of the native socket implementation. | |
1265 /** | |
1266 * This function is used to modify the non-blocking mode of the underlying | |
1267 * native socket. It has no effect on the behaviour of the socket object's | |
1268 * synchronous operations. | |
1269 * | |
1270 * @param mode If @c true, the underlying socket is put into non-blocking | |
1271 * mode and direct system calls may fail with boost::asio::error::would_block | |
1272 * (or the equivalent system error). | |
1273 * | |
1274 * @param ec Set to indicate what error occurred, if any. If the @c mode is | |
1275 * @c false, but the current value of @c non_blocking() is @c true, this | |
1276 * function fails with boost::asio::error::invalid_argument, as the | |
1277 * combination does not make sense. | |
1278 * | |
1279 * @par Example | |
1280 * This function is intended to allow the encapsulation of arbitrary | |
1281 * non-blocking system calls as asynchronous operations, in a way that is | |
1282 * transparent to the user of the socket object. The following example | |
1283 * illustrates how Linux's @c sendfile system call might be encapsulated: | |
1284 * @code template <typename Handler> | |
1285 * struct sendfile_op | |
1286 * { | |
1287 * tcp::socket& sock_; | |
1288 * int fd_; | |
1289 * Handler handler_; | |
1290 * off_t offset_; | |
1291 * std::size_t total_bytes_transferred_; | |
1292 * | |
1293 * // Function call operator meeting WriteHandler requirements. | |
1294 * // Used as the handler for the async_write_some operation. | |
1295 * void operator()(boost::system::error_code ec, std::size_t) | |
1296 * { | |
1297 * // Put the underlying socket into non-blocking mode. | |
1298 * if (!ec) | |
1299 * if (!sock_.native_non_blocking()) | |
1300 * sock_.native_non_blocking(true, ec); | |
1301 * | |
1302 * if (!ec) | |
1303 * { | |
1304 * for (;;) | |
1305 * { | |
1306 * // Try the system call. | |
1307 * errno = 0; | |
1308 * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); | |
1309 * ec = boost::system::error_code(n < 0 ? errno : 0, | |
1310 * boost::asio::error::get_system_category()); | |
1311 * total_bytes_transferred_ += ec ? 0 : n; | |
1312 * | |
1313 * // Retry operation immediately if interrupted by signal. | |
1314 * if (ec == boost::asio::error::interrupted) | |
1315 * continue; | |
1316 * | |
1317 * // Check if we need to run the operation again. | |
1318 * if (ec == boost::asio::error::would_block | |
1319 * || ec == boost::asio::error::try_again) | |
1320 * { | |
1321 * // We have to wait for the socket to become ready again. | |
1322 * sock_.async_write_some(boost::asio::null_buffers(), *this); | |
1323 * return; | |
1324 * } | |
1325 * | |
1326 * if (ec || n == 0) | |
1327 * { | |
1328 * // An error occurred, or we have reached the end of the file. | |
1329 * // Either way we must exit the loop so we can call the handler. | |
1330 * break; | |
1331 * } | |
1332 * | |
1333 * // Loop around to try calling sendfile again. | |
1334 * } | |
1335 * } | |
1336 * | |
1337 * // Pass result back to user's handler. | |
1338 * handler_(ec, total_bytes_transferred_); | |
1339 * } | |
1340 * }; | |
1341 * | |
1342 * template <typename Handler> | |
1343 * void async_sendfile(tcp::socket& sock, int fd, Handler h) | |
1344 * { | |
1345 * sendfile_op<Handler> op = { sock, fd, h, 0, 0 }; | |
1346 * sock.async_write_some(boost::asio::null_buffers(), op); | |
1347 * } @endcode | |
1348 */ | |
1349 boost::system::error_code native_non_blocking( | |
1350 bool mode, boost::system::error_code& ec) | |
1351 { | |
1352 return this->get_service().native_non_blocking( | |
1353 this->get_implementation(), mode, ec); | |
1354 } | |
1355 | |
1356 /// Get the local endpoint of the socket. | |
1357 /** | |
1358 * This function is used to obtain the locally bound endpoint of the socket. | |
1359 * | |
1360 * @returns An object that represents the local endpoint of the socket. | |
1361 * | |
1362 * @throws boost::system::system_error Thrown on failure. | |
1363 * | |
1364 * @par Example | |
1365 * @code | |
1366 * boost::asio::ip::tcp::socket socket(io_service); | |
1367 * ... | |
1368 * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(); | |
1369 * @endcode | |
1370 */ | |
1371 endpoint_type local_endpoint() const | |
1372 { | |
1373 boost::system::error_code ec; | |
1374 endpoint_type ep = this->get_service().local_endpoint( | |
1375 this->get_implementation(), ec); | |
1376 boost::asio::detail::throw_error(ec, "local_endpoint"); | |
1377 return ep; | |
1378 } | |
1379 | |
1380 /// Get the local endpoint of the socket. | |
1381 /** | |
1382 * This function is used to obtain the locally bound endpoint of the socket. | |
1383 * | |
1384 * @param ec Set to indicate what error occurred, if any. | |
1385 * | |
1386 * @returns An object that represents the local endpoint of the socket. | |
1387 * Returns a default-constructed endpoint object if an error occurred. | |
1388 * | |
1389 * @par Example | |
1390 * @code | |
1391 * boost::asio::ip::tcp::socket socket(io_service); | |
1392 * ... | |
1393 * boost::system::error_code ec; | |
1394 * boost::asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec); | |
1395 * if (ec) | |
1396 * { | |
1397 * // An error occurred. | |
1398 * } | |
1399 * @endcode | |
1400 */ | |
1401 endpoint_type local_endpoint(boost::system::error_code& ec) const | |
1402 { | |
1403 return this->get_service().local_endpoint(this->get_implementation(), ec); | |
1404 } | |
1405 | |
1406 /// Get the remote endpoint of the socket. | |
1407 /** | |
1408 * This function is used to obtain the remote endpoint of the socket. | |
1409 * | |
1410 * @returns An object that represents the remote endpoint of the socket. | |
1411 * | |
1412 * @throws boost::system::system_error Thrown on failure. | |
1413 * | |
1414 * @par Example | |
1415 * @code | |
1416 * boost::asio::ip::tcp::socket socket(io_service); | |
1417 * ... | |
1418 * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(); | |
1419 * @endcode | |
1420 */ | |
1421 endpoint_type remote_endpoint() const | |
1422 { | |
1423 boost::system::error_code ec; | |
1424 endpoint_type ep = this->get_service().remote_endpoint( | |
1425 this->get_implementation(), ec); | |
1426 boost::asio::detail::throw_error(ec, "remote_endpoint"); | |
1427 return ep; | |
1428 } | |
1429 | |
1430 /// Get the remote endpoint of the socket. | |
1431 /** | |
1432 * This function is used to obtain the remote endpoint of the socket. | |
1433 * | |
1434 * @param ec Set to indicate what error occurred, if any. | |
1435 * | |
1436 * @returns An object that represents the remote endpoint of the socket. | |
1437 * Returns a default-constructed endpoint object if an error occurred. | |
1438 * | |
1439 * @par Example | |
1440 * @code | |
1441 * boost::asio::ip::tcp::socket socket(io_service); | |
1442 * ... | |
1443 * boost::system::error_code ec; | |
1444 * boost::asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec); | |
1445 * if (ec) | |
1446 * { | |
1447 * // An error occurred. | |
1448 * } | |
1449 * @endcode | |
1450 */ | |
1451 endpoint_type remote_endpoint(boost::system::error_code& ec) const | |
1452 { | |
1453 return this->get_service().remote_endpoint(this->get_implementation(), ec); | |
1454 } | |
1455 | |
1456 /// Disable sends or receives on the socket. | |
1457 /** | |
1458 * This function is used to disable send operations, receive operations, or | |
1459 * both. | |
1460 * | |
1461 * @param what Determines what types of operation will no longer be allowed. | |
1462 * | |
1463 * @throws boost::system::system_error Thrown on failure. | |
1464 * | |
1465 * @par Example | |
1466 * Shutting down the send side of the socket: | |
1467 * @code | |
1468 * boost::asio::ip::tcp::socket socket(io_service); | |
1469 * ... | |
1470 * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send); | |
1471 * @endcode | |
1472 */ | |
1473 void shutdown(shutdown_type what) | |
1474 { | |
1475 boost::system::error_code ec; | |
1476 this->get_service().shutdown(this->get_implementation(), what, ec); | |
1477 boost::asio::detail::throw_error(ec, "shutdown"); | |
1478 } | |
1479 | |
1480 /// Disable sends or receives on the socket. | |
1481 /** | |
1482 * This function is used to disable send operations, receive operations, or | |
1483 * both. | |
1484 * | |
1485 * @param what Determines what types of operation will no longer be allowed. | |
1486 * | |
1487 * @param ec Set to indicate what error occurred, if any. | |
1488 * | |
1489 * @par Example | |
1490 * Shutting down the send side of the socket: | |
1491 * @code | |
1492 * boost::asio::ip::tcp::socket socket(io_service); | |
1493 * ... | |
1494 * boost::system::error_code ec; | |
1495 * socket.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec); | |
1496 * if (ec) | |
1497 * { | |
1498 * // An error occurred. | |
1499 * } | |
1500 * @endcode | |
1501 */ | |
1502 boost::system::error_code shutdown(shutdown_type what, | |
1503 boost::system::error_code& ec) | |
1504 { | |
1505 return this->get_service().shutdown(this->get_implementation(), what, ec); | |
1506 } | |
1507 | |
1508 protected: | |
1509 /// Protected destructor to prevent deletion through this type. | |
1510 ~basic_socket() | |
1511 { | |
1512 } | |
1513 }; | |
1514 | |
1515 } // namespace asio | |
1516 } // namespace boost | |
1517 | |
1518 #include <boost/asio/detail/pop_options.hpp> | |
1519 | |
1520 #endif // BOOST_ASIO_BASIC_SOCKET_HPP |