5
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
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)
11
#ifndef ASIO_BASIC_SOCKET_HPP
12
#define ASIO_BASIC_SOCKET_HPP
14
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
16
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18
#include "asio/detail/push_options.hpp"
20
#include "asio/basic_io_object.hpp"
21
#include "asio/error.hpp"
22
#include "asio/socket_base.hpp"
23
#include "asio/detail/throw_error.hpp"
27
/// Provides socket functionality.
29
* The basic_socket class template provides functionality that is common to both
30
* stream-oriented and datagram-oriented sockets.
33
* @e Distinct @e objects: Safe.@n
34
* @e Shared @e objects: Unsafe.
36
template <typename Protocol, typename SocketService>
38
: public basic_io_object<SocketService>,
42
/// The native representation of a socket.
43
typedef typename SocketService::native_type native_type;
45
/// The protocol type.
46
typedef Protocol protocol_type;
48
/// The endpoint type.
49
typedef typename Protocol::endpoint endpoint_type;
51
/// A basic_socket is always the lowest layer.
52
typedef basic_socket<Protocol, SocketService> lowest_layer_type;
54
/// Construct a basic_socket without opening it.
56
* This constructor creates a socket without opening it.
58
* @param io_service The io_service object that the socket will use to
59
* dispatch handlers for any asynchronous operations performed on the socket.
61
explicit basic_socket(asio::io_service& io_service)
62
: basic_io_object<SocketService>(io_service)
66
/// Construct and open a basic_socket.
68
* This constructor creates and opens a socket.
70
* @param io_service The io_service object that the socket will use to
71
* dispatch handlers for any asynchronous operations performed on the socket.
73
* @param protocol An object specifying protocol parameters to be used.
75
* @throws asio::system_error Thrown on failure.
77
basic_socket(asio::io_service& io_service,
78
const protocol_type& protocol)
79
: basic_io_object<SocketService>(io_service)
82
this->service.open(this->implementation, protocol, ec);
83
asio::detail::throw_error(ec);
86
/// Construct a basic_socket, opening it and binding it to the given local
89
* This constructor creates a socket and automatically opens it bound to the
90
* specified endpoint on the local machine. The protocol used is the protocol
91
* associated with the given endpoint.
93
* @param io_service The io_service object that the socket will use to
94
* dispatch handlers for any asynchronous operations performed on the socket.
96
* @param endpoint An endpoint on the local machine to which the socket will
99
* @throws asio::system_error Thrown on failure.
101
basic_socket(asio::io_service& io_service,
102
const endpoint_type& endpoint)
103
: basic_io_object<SocketService>(io_service)
106
this->service.open(this->implementation, endpoint.protocol(), ec);
107
asio::detail::throw_error(ec);
108
this->service.bind(this->implementation, endpoint, ec);
109
asio::detail::throw_error(ec);
112
/// Construct a basic_socket on an existing native socket.
114
* This constructor creates a socket object to hold an existing native socket.
116
* @param io_service The io_service object that the socket will use to
117
* dispatch handlers for any asynchronous operations performed on the socket.
119
* @param protocol An object specifying protocol parameters to be used.
121
* @param native_socket A native socket.
123
* @throws asio::system_error Thrown on failure.
125
basic_socket(asio::io_service& io_service,
126
const protocol_type& protocol, const native_type& native_socket)
127
: basic_io_object<SocketService>(io_service)
130
this->service.assign(this->implementation, protocol, native_socket, ec);
131
asio::detail::throw_error(ec);
134
/// Get a reference to the lowest layer.
136
* This function returns a reference to the lowest layer in a stack of
137
* layers. Since a basic_socket cannot contain any further layers, it simply
138
* returns a reference to itself.
140
* @return A reference to the lowest layer in the stack of layers. Ownership
141
* is not transferred to the caller.
143
lowest_layer_type& lowest_layer()
148
/// Open the socket using the specified protocol.
150
* This function opens the socket so that it will use the specified protocol.
152
* @param protocol An object specifying protocol parameters to be used.
154
* @throws asio::system_error Thrown on failure.
158
* asio::ip::tcp::socket socket(io_service);
159
* socket.open(asio::ip::tcp::v4());
162
void open(const protocol_type& protocol = protocol_type())
165
this->service.open(this->implementation, protocol, ec);
166
asio::detail::throw_error(ec);
169
/// Open the socket using the specified protocol.
171
* This function opens the socket so that it will use the specified protocol.
173
* @param protocol An object specifying which protocol is to be used.
175
* @param ec Set to indicate what error occurred, if any.
179
* asio::ip::tcp::socket socket(io_service);
180
* asio::error_code ec;
181
* socket.open(asio::ip::tcp::v4(), ec);
184
* // An error occurred.
188
asio::error_code open(const protocol_type& protocol,
189
asio::error_code& ec)
191
return this->service.open(this->implementation, protocol, ec);
194
/// Assign an existing native socket to the socket.
196
* This function opens the socket to hold an existing native socket.
198
* @param protocol An object specifying which protocol is to be used.
200
* @param native_socket A native socket.
202
* @throws asio::system_error Thrown on failure.
204
void assign(const protocol_type& protocol, const native_type& native_socket)
207
this->service.assign(this->implementation, protocol, native_socket, ec);
208
asio::detail::throw_error(ec);
211
/// Assign an existing native socket to the socket.
213
* This function opens the socket to hold an existing native socket.
215
* @param protocol An object specifying which protocol is to be used.
217
* @param native_socket A native socket.
219
* @param ec Set to indicate what error occurred, if any.
221
asio::error_code assign(const protocol_type& protocol,
222
const native_type& native_socket, asio::error_code& ec)
224
return this->service.assign(this->implementation,
225
protocol, native_socket, ec);
228
/// Determine whether the socket is open.
231
return this->service.is_open(this->implementation);
234
/// Close the socket.
236
* This function is used to close the socket. Any asynchronous send, receive
237
* or connect operations will be cancelled immediately, and will complete
238
* with the asio::error::operation_aborted error.
240
* @throws asio::system_error Thrown on failure.
242
* @note For portable behaviour with respect to graceful closure of a
243
* connected socket, call shutdown() before closing the socket.
248
this->service.close(this->implementation, ec);
249
asio::detail::throw_error(ec);
252
/// Close the socket.
254
* This function is used to close the socket. Any asynchronous send, receive
255
* or connect operations will be cancelled immediately, and will complete
256
* with the asio::error::operation_aborted error.
258
* @param ec Set to indicate what error occurred, if any.
262
* asio::ip::tcp::socket socket(io_service);
264
* asio::error_code ec;
268
* // An error occurred.
272
* @note For portable behaviour with respect to graceful closure of a
273
* connected socket, call shutdown() before closing the socket.
275
asio::error_code close(asio::error_code& ec)
277
return this->service.close(this->implementation, ec);
280
/// Get the native socket representation.
282
* This function may be used to obtain the underlying representation of the
283
* socket. This is intended to allow access to native socket functionality
284
* that is not otherwise provided.
288
return this->service.native(this->implementation);
291
/// Cancel all asynchronous operations associated with the socket.
293
* This function causes all outstanding asynchronous connect, send and receive
294
* operations to finish immediately, and the handlers for cancelled operations
295
* will be passed the asio::error::operation_aborted error.
297
* @throws asio::system_error Thrown on failure.
302
this->service.cancel(this->implementation, ec);
303
asio::detail::throw_error(ec);
306
/// Cancel all asynchronous operations associated with the socket.
308
* This function causes all outstanding asynchronous connect, send and receive
309
* operations to finish immediately, and the handlers for cancelled operations
310
* will be passed the asio::error::operation_aborted error.
312
* @param ec Set to indicate what error occurred, if any.
314
asio::error_code cancel(asio::error_code& ec)
316
return this->service.cancel(this->implementation, ec);
319
/// Determine whether the socket is at the out-of-band data mark.
321
* This function is used to check whether the socket input is currently
322
* positioned at the out-of-band data mark.
324
* @return A bool indicating whether the socket is at the out-of-band data
327
* @throws asio::system_error Thrown on failure.
332
bool b = this->service.at_mark(this->implementation, ec);
333
asio::detail::throw_error(ec);
337
/// Determine whether the socket is at the out-of-band data mark.
339
* This function is used to check whether the socket input is currently
340
* positioned at the out-of-band data mark.
342
* @param ec Set to indicate what error occurred, if any.
344
* @return A bool indicating whether the socket is at the out-of-band data
347
bool at_mark(asio::error_code& ec) const
349
return this->service.at_mark(this->implementation, ec);
352
/// Determine the number of bytes available for reading.
354
* This function is used to determine the number of bytes that may be read
357
* @return The number of bytes that may be read without blocking, or 0 if an
360
* @throws asio::system_error Thrown on failure.
362
std::size_t available() const
365
std::size_t s = this->service.available(this->implementation, ec);
366
asio::detail::throw_error(ec);
370
/// Determine the number of bytes available for reading.
372
* This function is used to determine the number of bytes that may be read
375
* @param ec Set to indicate what error occurred, if any.
377
* @return The number of bytes that may be read without blocking, or 0 if an
380
std::size_t available(asio::error_code& ec) const
382
return this->service.available(this->implementation, ec);
385
/// Bind the socket to the given local endpoint.
387
* This function binds the socket to the specified endpoint on the local
390
* @param endpoint An endpoint on the local machine to which the socket will
393
* @throws asio::system_error Thrown on failure.
397
* asio::ip::tcp::socket socket(io_service);
398
* socket.open(asio::ip::tcp::v4());
399
* socket.bind(asio::ip::tcp::endpoint(
400
* asio::ip::tcp::v4(), 12345));
403
void bind(const endpoint_type& endpoint)
406
this->service.bind(this->implementation, endpoint, ec);
407
asio::detail::throw_error(ec);
410
/// Bind the socket to the given local endpoint.
412
* This function binds the socket to the specified endpoint on the local
415
* @param endpoint An endpoint on the local machine to which the socket will
418
* @param ec Set to indicate what error occurred, if any.
422
* asio::ip::tcp::socket socket(io_service);
423
* socket.open(asio::ip::tcp::v4());
424
* asio::error_code ec;
425
* socket.bind(asio::ip::tcp::endpoint(
426
* asio::ip::tcp::v4(), 12345), ec);
429
* // An error occurred.
433
asio::error_code bind(const endpoint_type& endpoint,
434
asio::error_code& ec)
436
return this->service.bind(this->implementation, endpoint, ec);
439
/// Connect the socket to the specified endpoint.
441
* This function is used to connect a socket to the specified remote endpoint.
442
* The function call will block until the connection is successfully made or
445
* The socket is automatically opened if it is not already open. If the
446
* connect fails, and the socket was automatically opened, the socket is
447
* returned to the closed state.
449
* @param peer_endpoint The remote endpoint to which the socket will be
452
* @throws asio::system_error Thrown on failure.
456
* asio::ip::tcp::socket socket(io_service);
457
* asio::ip::tcp::endpoint endpoint(
458
* asio::ip::address::from_string("1.2.3.4"), 12345);
459
* socket.connect(endpoint);
462
void connect(const endpoint_type& peer_endpoint)
467
this->service.open(this->implementation, peer_endpoint.protocol(), ec);
468
asio::detail::throw_error(ec);
470
this->service.connect(this->implementation, peer_endpoint, ec);
471
asio::detail::throw_error(ec);
474
/// Connect the socket to the specified endpoint.
476
* This function is used to connect a socket to the specified remote endpoint.
477
* The function call will block until the connection is successfully made or
480
* The socket is automatically opened if it is not already open. If the
481
* connect fails, and the socket was automatically opened, the socket is
482
* returned to the closed state.
484
* @param peer_endpoint The remote endpoint to which the socket will be
487
* @param ec Set to indicate what error occurred, if any.
491
* asio::ip::tcp::socket socket(io_service);
492
* asio::ip::tcp::endpoint endpoint(
493
* asio::ip::address::from_string("1.2.3.4"), 12345);
494
* asio::error_code ec;
495
* socket.connect(endpoint, ec);
498
* // An error occurred.
502
asio::error_code connect(const endpoint_type& peer_endpoint,
503
asio::error_code& ec)
507
if (this->service.open(this->implementation,
508
peer_endpoint.protocol(), ec))
514
return this->service.connect(this->implementation, peer_endpoint, ec);
517
/// Start an asynchronous connect.
519
* This function is used to asynchronously connect a socket to the specified
520
* remote endpoint. The function call always returns immediately.
522
* The socket is automatically opened if it is not already open. If the
523
* connect fails, and the socket was automatically opened, the socket is
524
* returned to the closed state.
526
* @param peer_endpoint The remote endpoint to which the socket will be
527
* connected. Copies will be made of the endpoint object as required.
529
* @param handler The handler to be called when the connection operation
530
* completes. Copies will be made of the handler as required. The function
531
* signature of the handler must be:
532
* @code void handler(
533
* const asio::error_code& error // Result of operation
535
* Regardless of whether the asynchronous operation completes immediately or
536
* not, the handler will not be invoked from within this function. Invocation
537
* of the handler will be performed in a manner equivalent to using
538
* asio::io_service::post().
542
* void connect_handler(const asio::error_code& error)
546
* // Connect succeeded.
552
* asio::ip::tcp::socket socket(io_service);
553
* asio::ip::tcp::endpoint endpoint(
554
* asio::ip::address::from_string("1.2.3.4"), 12345);
555
* socket.async_connect(endpoint, connect_handler);
558
template <typename ConnectHandler>
559
void async_connect(const endpoint_type& peer_endpoint, ConnectHandler handler)
564
if (this->service.open(this->implementation,
565
peer_endpoint.protocol(), ec))
567
this->io_service().post(asio::detail::bind_handler(handler, ec));
572
this->service.async_connect(this->implementation, peer_endpoint, handler);
575
/// Set an option on the socket.
577
* This function is used to set an option on the socket.
579
* @param option The new option value to be set on the socket.
581
* @throws asio::system_error Thrown on failure.
583
* @sa SettableSocketOption @n
584
* asio::socket_base::broadcast @n
585
* asio::socket_base::do_not_route @n
586
* asio::socket_base::keep_alive @n
587
* asio::socket_base::linger @n
588
* asio::socket_base::receive_buffer_size @n
589
* asio::socket_base::receive_low_watermark @n
590
* asio::socket_base::reuse_address @n
591
* asio::socket_base::send_buffer_size @n
592
* asio::socket_base::send_low_watermark @n
593
* asio::ip::multicast::join_group @n
594
* asio::ip::multicast::leave_group @n
595
* asio::ip::multicast::enable_loopback @n
596
* asio::ip::multicast::outbound_interface @n
597
* asio::ip::multicast::hops @n
598
* asio::ip::tcp::no_delay
601
* Setting the IPPROTO_TCP/TCP_NODELAY option:
603
* asio::ip::tcp::socket socket(io_service);
605
* asio::ip::tcp::no_delay option(true);
606
* socket.set_option(option);
609
template <typename SettableSocketOption>
610
void set_option(const SettableSocketOption& option)
613
this->service.set_option(this->implementation, option, ec);
614
asio::detail::throw_error(ec);
617
/// Set an option on the socket.
619
* This function is used to set an option on the socket.
621
* @param option The new option value to be set on the socket.
623
* @param ec Set to indicate what error occurred, if any.
625
* @sa SettableSocketOption @n
626
* asio::socket_base::broadcast @n
627
* asio::socket_base::do_not_route @n
628
* asio::socket_base::keep_alive @n
629
* asio::socket_base::linger @n
630
* asio::socket_base::receive_buffer_size @n
631
* asio::socket_base::receive_low_watermark @n
632
* asio::socket_base::reuse_address @n
633
* asio::socket_base::send_buffer_size @n
634
* asio::socket_base::send_low_watermark @n
635
* asio::ip::multicast::join_group @n
636
* asio::ip::multicast::leave_group @n
637
* asio::ip::multicast::enable_loopback @n
638
* asio::ip::multicast::outbound_interface @n
639
* asio::ip::multicast::hops @n
640
* asio::ip::tcp::no_delay
643
* Setting the IPPROTO_TCP/TCP_NODELAY option:
645
* asio::ip::tcp::socket socket(io_service);
647
* asio::ip::tcp::no_delay option(true);
648
* asio::error_code ec;
649
* socket.set_option(option, ec);
652
* // An error occurred.
656
template <typename SettableSocketOption>
657
asio::error_code set_option(const SettableSocketOption& option,
658
asio::error_code& ec)
660
return this->service.set_option(this->implementation, option, ec);
663
/// Get an option from the socket.
665
* This function is used to get the current value of an option on the socket.
667
* @param option The option value to be obtained from the socket.
669
* @throws asio::system_error Thrown on failure.
671
* @sa GettableSocketOption @n
672
* asio::socket_base::broadcast @n
673
* asio::socket_base::do_not_route @n
674
* asio::socket_base::keep_alive @n
675
* asio::socket_base::linger @n
676
* asio::socket_base::receive_buffer_size @n
677
* asio::socket_base::receive_low_watermark @n
678
* asio::socket_base::reuse_address @n
679
* asio::socket_base::send_buffer_size @n
680
* asio::socket_base::send_low_watermark @n
681
* asio::ip::multicast::join_group @n
682
* asio::ip::multicast::leave_group @n
683
* asio::ip::multicast::enable_loopback @n
684
* asio::ip::multicast::outbound_interface @n
685
* asio::ip::multicast::hops @n
686
* asio::ip::tcp::no_delay
689
* Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:
691
* asio::ip::tcp::socket socket(io_service);
693
* asio::ip::tcp::socket::keep_alive option;
694
* socket.get_option(option);
695
* bool is_set = option.get();
698
template <typename GettableSocketOption>
699
void get_option(GettableSocketOption& option) const
702
this->service.get_option(this->implementation, option, ec);
703
asio::detail::throw_error(ec);
706
/// Get an option from the socket.
708
* This function is used to get the current value of an option on the socket.
710
* @param option The option value to be obtained from the socket.
712
* @param ec Set to indicate what error occurred, if any.
714
* @sa GettableSocketOption @n
715
* asio::socket_base::broadcast @n
716
* asio::socket_base::do_not_route @n
717
* asio::socket_base::keep_alive @n
718
* asio::socket_base::linger @n
719
* asio::socket_base::receive_buffer_size @n
720
* asio::socket_base::receive_low_watermark @n
721
* asio::socket_base::reuse_address @n
722
* asio::socket_base::send_buffer_size @n
723
* asio::socket_base::send_low_watermark @n
724
* asio::ip::multicast::join_group @n
725
* asio::ip::multicast::leave_group @n
726
* asio::ip::multicast::enable_loopback @n
727
* asio::ip::multicast::outbound_interface @n
728
* asio::ip::multicast::hops @n
729
* asio::ip::tcp::no_delay
732
* Getting the value of the SOL_SOCKET/SO_KEEPALIVE option:
734
* asio::ip::tcp::socket socket(io_service);
736
* asio::ip::tcp::socket::keep_alive option;
737
* asio::error_code ec;
738
* socket.get_option(option, ec);
741
* // An error occurred.
743
* bool is_set = option.get();
746
template <typename GettableSocketOption>
747
asio::error_code get_option(GettableSocketOption& option,
748
asio::error_code& ec) const
750
return this->service.get_option(this->implementation, option, ec);
753
/// Perform an IO control command on the socket.
755
* This function is used to execute an IO control command on the socket.
757
* @param command The IO control command to be performed on the socket.
759
* @throws asio::system_error Thrown on failure.
761
* @sa IoControlCommand @n
762
* asio::socket_base::bytes_readable @n
763
* asio::socket_base::non_blocking_io
766
* Getting the number of bytes ready to read:
768
* asio::ip::tcp::socket socket(io_service);
770
* asio::ip::tcp::socket::bytes_readable command;
771
* socket.io_control(command);
772
* std::size_t bytes_readable = command.get();
775
template <typename IoControlCommand>
776
void io_control(IoControlCommand& command)
779
this->service.io_control(this->implementation, command, ec);
780
asio::detail::throw_error(ec);
783
/// Perform an IO control command on the socket.
785
* This function is used to execute an IO control command on the socket.
787
* @param command The IO control command to be performed on the socket.
789
* @param ec Set to indicate what error occurred, if any.
791
* @sa IoControlCommand @n
792
* asio::socket_base::bytes_readable @n
793
* asio::socket_base::non_blocking_io
796
* Getting the number of bytes ready to read:
798
* asio::ip::tcp::socket socket(io_service);
800
* asio::ip::tcp::socket::bytes_readable command;
801
* asio::error_code ec;
802
* socket.io_control(command, ec);
805
* // An error occurred.
807
* std::size_t bytes_readable = command.get();
810
template <typename IoControlCommand>
811
asio::error_code io_control(IoControlCommand& command,
812
asio::error_code& ec)
814
return this->service.io_control(this->implementation, command, ec);
817
/// Get the local endpoint of the socket.
819
* This function is used to obtain the locally bound endpoint of the socket.
821
* @returns An object that represents the local endpoint of the socket.
823
* @throws asio::system_error Thrown on failure.
827
* asio::ip::tcp::socket socket(io_service);
829
* asio::ip::tcp::endpoint endpoint = socket.local_endpoint();
832
endpoint_type local_endpoint() const
835
endpoint_type ep = this->service.local_endpoint(this->implementation, ec);
836
asio::detail::throw_error(ec);
840
/// Get the local endpoint of the socket.
842
* This function is used to obtain the locally bound endpoint of the socket.
844
* @param ec Set to indicate what error occurred, if any.
846
* @returns An object that represents the local endpoint of the socket.
847
* Returns a default-constructed endpoint object if an error occurred.
851
* asio::ip::tcp::socket socket(io_service);
853
* asio::error_code ec;
854
* asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec);
857
* // An error occurred.
861
endpoint_type local_endpoint(asio::error_code& ec) const
863
return this->service.local_endpoint(this->implementation, ec);
866
/// Get the remote endpoint of the socket.
868
* This function is used to obtain the remote endpoint of the socket.
870
* @returns An object that represents the remote endpoint of the socket.
872
* @throws asio::system_error Thrown on failure.
876
* asio::ip::tcp::socket socket(io_service);
878
* asio::ip::tcp::endpoint endpoint = socket.remote_endpoint();
881
endpoint_type remote_endpoint() const
884
endpoint_type ep = this->service.remote_endpoint(this->implementation, ec);
885
asio::detail::throw_error(ec);
889
/// Get the remote endpoint of the socket.
891
* This function is used to obtain the remote endpoint of the socket.
893
* @param ec Set to indicate what error occurred, if any.
895
* @returns An object that represents the remote endpoint of the socket.
896
* Returns a default-constructed endpoint object if an error occurred.
900
* asio::ip::tcp::socket socket(io_service);
902
* asio::error_code ec;
903
* asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec);
906
* // An error occurred.
910
endpoint_type remote_endpoint(asio::error_code& ec) const
912
return this->service.remote_endpoint(this->implementation, ec);
915
/// Disable sends or receives on the socket.
917
* This function is used to disable send operations, receive operations, or
920
* @param what Determines what types of operation will no longer be allowed.
922
* @throws asio::system_error Thrown on failure.
925
* Shutting down the send side of the socket:
927
* asio::ip::tcp::socket socket(io_service);
929
* socket.shutdown(asio::ip::tcp::socket::shutdown_send);
932
void shutdown(shutdown_type what)
935
this->service.shutdown(this->implementation, what, ec);
936
asio::detail::throw_error(ec);
939
/// Disable sends or receives on the socket.
941
* This function is used to disable send operations, receive operations, or
944
* @param what Determines what types of operation will no longer be allowed.
946
* @param ec Set to indicate what error occurred, if any.
949
* Shutting down the send side of the socket:
951
* asio::ip::tcp::socket socket(io_service);
953
* asio::error_code ec;
954
* socket.shutdown(asio::ip::tcp::socket::shutdown_send, ec);
957
* // An error occurred.
961
asio::error_code shutdown(shutdown_type what,
962
asio::error_code& ec)
964
return this->service.shutdown(this->implementation, what, ec);
968
/// Protected destructor to prevent deletion through this type.
976
#include "asio/detail/pop_options.hpp"
978
#endif // ASIO_BASIC_SOCKET_HPP