10ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// 20ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// basic_socket.hpp 30ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// ~~~~~~~~~~~~~~~~ 40ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// 50ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) 60ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// 70ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// Distributed under the Boost Software License, Version 1.0. (See accompanying 80ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 90ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie// 100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#ifndef ASIO_BASIC_SOCKET_HPP 120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#define ASIO_BASIC_SOCKET_HPP 130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/config.hpp" 160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/async_result.hpp" 170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/basic_io_object.hpp" 180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/handler_type_requirements.hpp" 190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/throw_error.hpp" 200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/type_traits.hpp" 210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/error.hpp" 220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/socket_base.hpp" 230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/push_options.hpp" 250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffienamespace asio { 270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie/// Provides socket functionality. 290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie/** 300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * The basic_socket class template provides functionality that is common to both 310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * stream-oriented and datagram-oriented sockets. 320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @par Thread Safety 340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @e Distinct @e objects: Safe.@n 350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @e Shared @e objects: Unsafe. 360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffietemplate <typename Protocol, typename SocketService> 380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieclass basic_socket 390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie : public basic_io_object<SocketService>, 400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie public socket_base 410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie{ 420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffiepublic: 430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// (Deprecated: Use native_handle_type.) The native representation of a 440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// socket. 450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie typedef typename SocketService::native_handle_type native_type; 460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// The native representation of a socket. 480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie typedef typename SocketService::native_handle_type native_handle_type; 490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// The protocol type. 510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie typedef Protocol protocol_type; 520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// The endpoint type. 540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie typedef typename Protocol::endpoint endpoint_type; 550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// A basic_socket is always the lowest layer. 570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie typedef basic_socket<Protocol, SocketService> lowest_layer_type; 580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Construct a basic_socket without opening it. 600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This constructor creates a socket without opening it. 620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param io_service The io_service object that the socket will use to 640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * dispatch handlers for any asynchronous operations performed on the socket. 650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie explicit basic_socket(asio::io_service& io_service) 670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie : basic_io_object<SocketService>(io_service) 680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Construct and open a basic_socket. 720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This constructor creates and opens a socket. 740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param io_service The io_service object that the socket will use to 760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * dispatch handlers for any asynchronous operations performed on the socket. 770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param protocol An object specifying protocol parameters to be used. 790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @throws asio::system_error Thrown on failure. 810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie basic_socket(asio::io_service& io_service, 830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie const protocol_type& protocol) 840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie : basic_io_object<SocketService>(io_service) 850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code ec; 870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie this->get_service().open(this->get_implementation(), protocol, ec); 880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::detail::throw_error(ec, "open"); 890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Construct a basic_socket, opening it and binding it to the given local 920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// endpoint. 930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This constructor creates a socket and automatically opens it bound to the 950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * specified endpoint on the local machine. The protocol used is the protocol 960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * associated with the given endpoint. 970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param io_service The io_service object that the socket will use to 990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * dispatch handlers for any asynchronous operations performed on the socket. 1000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 1010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param endpoint An endpoint on the local machine to which the socket will 1020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * be bound. 1030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 1040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @throws asio::system_error Thrown on failure. 1050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 1060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie basic_socket(asio::io_service& io_service, 1070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie const endpoint_type& endpoint) 1080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie : basic_io_object<SocketService>(io_service) 1090ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 1100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code ec; 1110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie const protocol_type protocol = endpoint.protocol(); 1120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie this->get_service().open(this->get_implementation(), protocol, ec); 1130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::detail::throw_error(ec, "open"); 1140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie this->get_service().bind(this->get_implementation(), endpoint, ec); 1150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::detail::throw_error(ec, "bind"); 1160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 1170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Construct a basic_socket on an existing native socket. 1190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 1200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This constructor creates a socket object to hold an existing native socket. 1210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 1220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param io_service The io_service object that the socket will use to 1230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * dispatch handlers for any asynchronous operations performed on the socket. 1240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 1250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param protocol An object specifying protocol parameters to be used. 1260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 1270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param native_socket A native socket. 1280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 1290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @throws asio::system_error Thrown on failure. 1300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 1310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie basic_socket(asio::io_service& io_service, 1320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie const protocol_type& protocol, const native_handle_type& native_socket) 1330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie : basic_io_object<SocketService>(io_service) 1340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 1350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code ec; 1360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie this->get_service().assign(this->get_implementation(), 1370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie protocol, native_socket, ec); 1380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::detail::throw_error(ec, "assign"); 1390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 1400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Move-construct a basic_socket from another. 1420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 1430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This constructor moves a socket from one object to another. 1440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 1450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param other The other basic_socket object from which the move will 1460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * occur. 1470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 1480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @note Following the move, the moved-from object is in the same state as if 1490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * constructed using the @c basic_socket(io_service&) constructor. 1500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 1510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie basic_socket(basic_socket&& other) 1520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie : basic_io_object<SocketService>( 1530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie ASIO_MOVE_CAST(basic_socket)(other)) 1540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 1550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 1560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Move-assign a basic_socket from another. 1580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 1590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This assignment operator moves a socket from one object to another. 1600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 1610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param other The other basic_socket object from which the move will 1620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * occur. 1630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 1640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @note Following the move, the moved-from object is in the same state as if 1650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * constructed using the @c basic_socket(io_service&) constructor. 1660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 1670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie basic_socket& operator=(basic_socket&& other) 1680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 1690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie basic_io_object<SocketService>::operator=( 1700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie ASIO_MOVE_CAST(basic_socket)(other)); 1710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return *this; 1720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 1730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // All sockets have access to each other's implementations. 1750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie template <typename Protocol1, typename SocketService1> 1760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie friend class basic_socket; 1770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Move-construct a basic_socket from a socket of another protocol type. 1790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 1800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This constructor moves a socket from one object to another. 1810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 1820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param other The other basic_socket object from which the move will 1830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * occur. 1840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 1850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @note Following the move, the moved-from object is in the same state as if 1860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * constructed using the @c basic_socket(io_service&) constructor. 1870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 1880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie template <typename Protocol1, typename SocketService1> 1890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie basic_socket(basic_socket<Protocol1, SocketService1>&& other, 1900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie typename enable_if<is_convertible<Protocol1, Protocol>::value>::type* = 0) 1910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie : basic_io_object<SocketService>(other.get_io_service()) 1920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 1930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie this->get_service().template converting_move_construct<Protocol1>( 1940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie this->get_implementation(), other.get_implementation()); 1950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 1960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 1970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Move-assign a basic_socket from a socket of another protocol type. 1980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 1990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This assignment operator moves a socket from one object to another. 2000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 2010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param other The other basic_socket object from which the move will 2020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * occur. 2030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 2040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @note Following the move, the moved-from object is in the same state as if 2050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * constructed using the @c basic_socket(io_service&) constructor. 2060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 2070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie template <typename Protocol1, typename SocketService1> 2080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie typename enable_if<is_convertible<Protocol1, Protocol>::value, 2090ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie basic_socket>::type& operator=( 2100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie basic_socket<Protocol1, SocketService1>&& other) 2110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 2120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie basic_socket tmp(ASIO_MOVE_CAST2(basic_socket< 2130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie Protocol1, SocketService1>)(other)); 2140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie basic_io_object<SocketService>::operator=( 2150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie ASIO_MOVE_CAST(basic_socket)(tmp)); 2160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return *this; 2170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 2180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 2190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Get a reference to the lowest layer. 2200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 2210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function returns a reference to the lowest layer in a stack of 2220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * layers. Since a basic_socket cannot contain any further layers, it simply 2230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * returns a reference to itself. 2240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 2250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @return A reference to the lowest layer in the stack of layers. Ownership 2260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * is not transferred to the caller. 2270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 2280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie lowest_layer_type& lowest_layer() 2290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 2300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return *this; 2310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 2320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 2330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Get a const reference to the lowest layer. 2340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 2350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function returns a const reference to the lowest layer in a stack of 2360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * layers. Since a basic_socket cannot contain any further layers, it simply 2370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * returns a reference to itself. 2380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 2390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @return A const reference to the lowest layer in the stack of layers. 2400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * Ownership is not transferred to the caller. 2410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 2420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie const lowest_layer_type& lowest_layer() const 2430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 2440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return *this; 2450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 2460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 2470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Open the socket using the specified protocol. 2480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 2490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function opens the socket so that it will use the specified protocol. 2500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 2510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param protocol An object specifying protocol parameters to be used. 2520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 2530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @throws asio::system_error Thrown on failure. 2540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 2550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @par Example 2560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @code 2570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::socket socket(io_service); 2580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * socket.open(asio::ip::tcp::v4()); 2590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @endcode 2600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 2610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie void open(const protocol_type& protocol = protocol_type()) 2620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 2630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code ec; 2640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie this->get_service().open(this->get_implementation(), protocol, ec); 2650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::detail::throw_error(ec, "open"); 2660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 2670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 2680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Open the socket using the specified protocol. 2690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 2700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function opens the socket so that it will use the specified protocol. 2710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 2720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param protocol An object specifying which protocol is to be used. 2730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 2740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param ec Set to indicate what error occurred, if any. 2750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 2760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @par Example 2770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @code 2780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::socket socket(io_service); 2790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::error_code ec; 2800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * socket.open(asio::ip::tcp::v4(), ec); 2810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * if (ec) 2820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 2830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // An error occurred. 2840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * } 2850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @endcode 2860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 2870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code open(const protocol_type& protocol, 2880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code& ec) 2890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 2900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return this->get_service().open(this->get_implementation(), protocol, ec); 2910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 2920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 2930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Assign an existing native socket to the socket. 2940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /* 2950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function opens the socket to hold an existing native socket. 2960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 2970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param protocol An object specifying which protocol is to be used. 2980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 2990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param native_socket A native socket. 3000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 3010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @throws asio::system_error Thrown on failure. 3020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 3030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie void assign(const protocol_type& protocol, 3040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie const native_handle_type& native_socket) 3050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 3060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code ec; 3070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie this->get_service().assign(this->get_implementation(), 3080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie protocol, native_socket, ec); 3090ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::detail::throw_error(ec, "assign"); 3100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 3110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 3120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Assign an existing native socket to the socket. 3130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /* 3140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function opens the socket to hold an existing native socket. 3150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 3160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param protocol An object specifying which protocol is to be used. 3170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 3180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param native_socket A native socket. 3190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 3200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param ec Set to indicate what error occurred, if any. 3210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 3220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code assign(const protocol_type& protocol, 3230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie const native_handle_type& native_socket, asio::error_code& ec) 3240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 3250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return this->get_service().assign(this->get_implementation(), 3260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie protocol, native_socket, ec); 3270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 3280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 3290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Determine whether the socket is open. 3300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie bool is_open() const 3310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 3320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return this->get_service().is_open(this->get_implementation()); 3330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 3340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 3350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Close the socket. 3360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 3370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function is used to close the socket. Any asynchronous send, receive 3380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * or connect operations will be cancelled immediately, and will complete 3390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * with the asio::error::operation_aborted error. 3400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 3410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @throws asio::system_error Thrown on failure. Note that, even if 3420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * the function indicates an error, the underlying descriptor is closed. 3430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 3440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @note For portable behaviour with respect to graceful closure of a 3450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * connected socket, call shutdown() before closing the socket. 3460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 3470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie void close() 3480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 3490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code ec; 3500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie this->get_service().close(this->get_implementation(), ec); 3510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::detail::throw_error(ec, "close"); 3520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 3530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 3540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Close the socket. 3550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 3560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function is used to close the socket. Any asynchronous send, receive 3570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * or connect operations will be cancelled immediately, and will complete 3580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * with the asio::error::operation_aborted error. 3590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 3600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param ec Set to indicate what error occurred, if any. Note that, even if 3610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * the function indicates an error, the underlying descriptor is closed. 3620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 3630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @par Example 3640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @code 3650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::socket socket(io_service); 3660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * ... 3670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::error_code ec; 3680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * socket.close(ec); 3690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * if (ec) 3700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 3710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // An error occurred. 3720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * } 3730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @endcode 3740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 3750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @note For portable behaviour with respect to graceful closure of a 3760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * connected socket, call shutdown() before closing the socket. 3770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 3780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code close(asio::error_code& ec) 3790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 3800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return this->get_service().close(this->get_implementation(), ec); 3810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 3820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 3830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// (Deprecated: Use native_handle().) Get the native socket representation. 3840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 3850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function may be used to obtain the underlying representation of the 3860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * socket. This is intended to allow access to native socket functionality 3870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * that is not otherwise provided. 3880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 3890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie native_type native() 3900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 3910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return this->get_service().native_handle(this->get_implementation()); 3920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 3930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 3940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Get the native socket representation. 3950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 3960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function may be used to obtain the underlying representation of the 3970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * socket. This is intended to allow access to native socket functionality 3980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * that is not otherwise provided. 3990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 4000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie native_handle_type native_handle() 4010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 4020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return this->get_service().native_handle(this->get_implementation()); 4030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 4040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 4050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Cancel all asynchronous operations associated with the socket. 4060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 4070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function causes all outstanding asynchronous connect, send and receive 4080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * operations to finish immediately, and the handlers for cancelled operations 4090ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * will be passed the asio::error::operation_aborted error. 4100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 4110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @throws asio::system_error Thrown on failure. 4120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 4130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @note Calls to cancel() will always fail with 4140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::error::operation_not_supported when run on Windows XP, Windows 4150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * Server 2003, and earlier versions of Windows, unless 4160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has 4170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * two issues that should be considered before enabling its use: 4180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 4190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @li It will only cancel asynchronous operations that were initiated in the 4200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * current thread. 4210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 4220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @li It can appear to complete without error, but the request to cancel the 4230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * unfinished operations may be silently ignored by the operating system. 4240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * Whether it works or not seems to depend on the drivers that are installed. 4250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 4260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * For portable cancellation, consider using one of the following 4270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * alternatives: 4280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 4290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @li Disable asio's I/O completion port backend by defining 4300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * ASIO_DISABLE_IOCP. 4310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 4320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @li Use the close() function to simultaneously cancel the outstanding 4330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * operations and close the socket. 4340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 4350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * When running on Windows Vista, Windows Server 2008, and later, the 4360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * CancelIoEx function is always used. This function does not have the 4370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * problems described above. 4380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 4390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie void cancel() 4400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 4410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code ec; 4420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie this->get_service().cancel(this->get_implementation(), ec); 4430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::detail::throw_error(ec, "cancel"); 4440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 4450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 4460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Cancel all asynchronous operations associated with the socket. 4470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 4480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function causes all outstanding asynchronous connect, send and receive 4490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * operations to finish immediately, and the handlers for cancelled operations 4500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * will be passed the asio::error::operation_aborted error. 4510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 4520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param ec Set to indicate what error occurred, if any. 4530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 4540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @note Calls to cancel() will always fail with 4550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::error::operation_not_supported when run on Windows XP, Windows 4560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * Server 2003, and earlier versions of Windows, unless 4570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has 4580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * two issues that should be considered before enabling its use: 4590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 4600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @li It will only cancel asynchronous operations that were initiated in the 4610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * current thread. 4620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 4630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @li It can appear to complete without error, but the request to cancel the 4640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * unfinished operations may be silently ignored by the operating system. 4650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * Whether it works or not seems to depend on the drivers that are installed. 4660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 4670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * For portable cancellation, consider using one of the following 4680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * alternatives: 4690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 4700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @li Disable asio's I/O completion port backend by defining 4710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * ASIO_DISABLE_IOCP. 4720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 4730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @li Use the close() function to simultaneously cancel the outstanding 4740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * operations and close the socket. 4750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 4760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * When running on Windows Vista, Windows Server 2008, and later, the 4770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * CancelIoEx function is always used. This function does not have the 4780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * problems described above. 4790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 4800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code cancel(asio::error_code& ec) 4810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 4820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return this->get_service().cancel(this->get_implementation(), ec); 4830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 4840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 4850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Determine whether the socket is at the out-of-band data mark. 4860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 4870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function is used to check whether the socket input is currently 4880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * positioned at the out-of-band data mark. 4890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 4900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @return A bool indicating whether the socket is at the out-of-band data 4910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * mark. 4920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 4930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @throws asio::system_error Thrown on failure. 4940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 4950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie bool at_mark() const 4960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 4970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code ec; 4980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie bool b = this->get_service().at_mark(this->get_implementation(), ec); 4990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::detail::throw_error(ec, "at_mark"); 5000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return b; 5010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 5020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 5030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Determine whether the socket is at the out-of-band data mark. 5040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 5050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function is used to check whether the socket input is currently 5060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * positioned at the out-of-band data mark. 5070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 5080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param ec Set to indicate what error occurred, if any. 5090ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 5100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @return A bool indicating whether the socket is at the out-of-band data 5110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * mark. 5120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 5130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie bool at_mark(asio::error_code& ec) const 5140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 5150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return this->get_service().at_mark(this->get_implementation(), ec); 5160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 5170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 5180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Determine the number of bytes available for reading. 5190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 5200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function is used to determine the number of bytes that may be read 5210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * without blocking. 5220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 5230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @return The number of bytes that may be read without blocking, or 0 if an 5240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * error occurs. 5250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 5260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @throws asio::system_error Thrown on failure. 5270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 5280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie std::size_t available() const 5290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 5300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code ec; 5310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie std::size_t s = this->get_service().available( 5320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie this->get_implementation(), ec); 5330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::detail::throw_error(ec, "available"); 5340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return s; 5350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 5360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 5370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Determine the number of bytes available for reading. 5380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 5390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function is used to determine the number of bytes that may be read 5400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * without blocking. 5410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 5420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param ec Set to indicate what error occurred, if any. 5430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 5440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @return The number of bytes that may be read without blocking, or 0 if an 5450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * error occurs. 5460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 5470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie std::size_t available(asio::error_code& ec) const 5480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 5490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return this->get_service().available(this->get_implementation(), ec); 5500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 5510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 5520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Bind the socket to the given local endpoint. 5530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 5540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function binds the socket to the specified endpoint on the local 5550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * machine. 5560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 5570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param endpoint An endpoint on the local machine to which the socket will 5580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * be bound. 5590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 5600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @throws asio::system_error Thrown on failure. 5610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 5620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @par Example 5630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @code 5640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::socket socket(io_service); 5650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * socket.open(asio::ip::tcp::v4()); 5660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * socket.bind(asio::ip::tcp::endpoint( 5670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::v4(), 12345)); 5680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @endcode 5690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 5700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie void bind(const endpoint_type& endpoint) 5710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 5720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code ec; 5730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie this->get_service().bind(this->get_implementation(), endpoint, ec); 5740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::detail::throw_error(ec, "bind"); 5750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 5760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 5770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Bind the socket to the given local endpoint. 5780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 5790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function binds the socket to the specified endpoint on the local 5800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * machine. 5810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 5820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param endpoint An endpoint on the local machine to which the socket will 5830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * be bound. 5840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 5850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param ec Set to indicate what error occurred, if any. 5860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 5870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @par Example 5880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @code 5890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::socket socket(io_service); 5900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * socket.open(asio::ip::tcp::v4()); 5910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::error_code ec; 5920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * socket.bind(asio::ip::tcp::endpoint( 5930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::v4(), 12345), ec); 5940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * if (ec) 5950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 5960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // An error occurred. 5970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * } 5980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @endcode 5990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 6000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code bind(const endpoint_type& endpoint, 6010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code& ec) 6020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 6030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return this->get_service().bind(this->get_implementation(), endpoint, ec); 6040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 6050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 6060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Connect the socket to the specified endpoint. 6070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 6080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function is used to connect a socket to the specified remote endpoint. 6090ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * The function call will block until the connection is successfully made or 6100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * an error occurs. 6110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 6120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * The socket is automatically opened if it is not already open. If the 6130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * connect fails, and the socket was automatically opened, the socket is 6140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * not returned to the closed state. 6150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 6160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param peer_endpoint The remote endpoint to which the socket will be 6170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * connected. 6180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 6190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @throws asio::system_error Thrown on failure. 6200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 6210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @par Example 6220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @code 6230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::socket socket(io_service); 6240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::endpoint endpoint( 6250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::address::from_string("1.2.3.4"), 12345); 6260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * socket.connect(endpoint); 6270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @endcode 6280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 6290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie void connect(const endpoint_type& peer_endpoint) 6300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 6310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code ec; 6320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie if (!is_open()) 6330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 6340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie this->get_service().open(this->get_implementation(), 6350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie peer_endpoint.protocol(), ec); 6360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::detail::throw_error(ec, "connect"); 6370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 6380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie this->get_service().connect(this->get_implementation(), peer_endpoint, ec); 6390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::detail::throw_error(ec, "connect"); 6400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 6410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 6420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Connect the socket to the specified endpoint. 6430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 6440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function is used to connect a socket to the specified remote endpoint. 6450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * The function call will block until the connection is successfully made or 6460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * an error occurs. 6470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 6480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * The socket is automatically opened if it is not already open. If the 6490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * connect fails, and the socket was automatically opened, the socket is 6500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * not returned to the closed state. 6510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 6520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param peer_endpoint The remote endpoint to which the socket will be 6530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * connected. 6540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 6550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param ec Set to indicate what error occurred, if any. 6560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 6570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @par Example 6580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @code 6590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::socket socket(io_service); 6600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::endpoint endpoint( 6610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::address::from_string("1.2.3.4"), 12345); 6620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::error_code ec; 6630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * socket.connect(endpoint, ec); 6640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * if (ec) 6650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 6660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // An error occurred. 6670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * } 6680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @endcode 6690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 6700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code connect(const endpoint_type& peer_endpoint, 6710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code& ec) 6720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 6730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie if (!is_open()) 6740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 6750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie if (this->get_service().open(this->get_implementation(), 6760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie peer_endpoint.protocol(), ec)) 6770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 6780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return ec; 6790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 6800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 6810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 6820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return this->get_service().connect( 6830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie this->get_implementation(), peer_endpoint, ec); 6840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 6850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 6860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Start an asynchronous connect. 6870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 6880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function is used to asynchronously connect a socket to the specified 6890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * remote endpoint. The function call always returns immediately. 6900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 6910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * The socket is automatically opened if it is not already open. If the 6920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * connect fails, and the socket was automatically opened, the socket is 6930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * not returned to the closed state. 6940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 6950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param peer_endpoint The remote endpoint to which the socket will be 6960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * connected. Copies will be made of the endpoint object as required. 6970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 6980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param handler The handler to be called when the connection operation 6990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * completes. Copies will be made of the handler as required. The function 7000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * signature of the handler must be: 7010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @code void handler( 7020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * const asio::error_code& error // Result of operation 7030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * ); @endcode 7040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * Regardless of whether the asynchronous operation completes immediately or 7050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * not, the handler will not be invoked from within this function. Invocation 7060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * of the handler will be performed in a manner equivalent to using 7070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::io_service::post(). 7080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 7090ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @par Example 7100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @code 7110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * void connect_handler(const asio::error_code& error) 7120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 7130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * if (!error) 7140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 7150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // Connect succeeded. 7160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * } 7170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * } 7180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 7190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * ... 7200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 7210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::socket socket(io_service); 7220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::endpoint endpoint( 7230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::address::from_string("1.2.3.4"), 12345); 7240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * socket.async_connect(endpoint, connect_handler); 7250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @endcode 7260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 7270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie template <typename ConnectHandler> 7280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie ASIO_INITFN_RESULT_TYPE(ConnectHandler, 7290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie void (asio::error_code)) 7300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie async_connect(const endpoint_type& peer_endpoint, 7310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie ASIO_MOVE_ARG(ConnectHandler) handler) 7320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 7330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // If you get an error on the following line it means that your handler does 7340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie // not meet the documented type requirements for a ConnectHandler. 7350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check; 7360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 7370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie if (!is_open()) 7380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 7390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code ec; 7400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie const protocol_type protocol = peer_endpoint.protocol(); 7410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie if (this->get_service().open(this->get_implementation(), protocol, ec)) 7420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 7430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie detail::async_result_init< 7440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie ConnectHandler, void (asio::error_code)> init( 7450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie ASIO_MOVE_CAST(ConnectHandler)(handler)); 7460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 7470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie this->get_io_service().post( 7480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::detail::bind_handler( 7490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie ASIO_MOVE_CAST(ASIO_HANDLER_TYPE( 7500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie ConnectHandler, void (asio::error_code)))( 7510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie init.handler), ec)); 7520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 7530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return init.result.get(); 7540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 7550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 7560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 7570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return this->get_service().async_connect(this->get_implementation(), 7580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie peer_endpoint, ASIO_MOVE_CAST(ConnectHandler)(handler)); 7590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 7600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 7610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Set an option on the socket. 7620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 7630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function is used to set an option on the socket. 7640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 7650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param option The new option value to be set on the socket. 7660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 7670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @throws asio::system_error Thrown on failure. 7680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 7690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @sa SettableSocketOption @n 7700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::broadcast @n 7710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::do_not_route @n 7720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::keep_alive @n 7730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::linger @n 7740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::receive_buffer_size @n 7750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::receive_low_watermark @n 7760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::reuse_address @n 7770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::send_buffer_size @n 7780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::send_low_watermark @n 7790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::multicast::join_group @n 7800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::multicast::leave_group @n 7810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::multicast::enable_loopback @n 7820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::multicast::outbound_interface @n 7830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::multicast::hops @n 7840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::no_delay 7850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 7860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @par Example 7870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * Setting the IPPROTO_TCP/TCP_NODELAY option: 7880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @code 7890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::socket socket(io_service); 7900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * ... 7910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::no_delay option(true); 7920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * socket.set_option(option); 7930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @endcode 7940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 7950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie template <typename SettableSocketOption> 7960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie void set_option(const SettableSocketOption& option) 7970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 7980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code ec; 7990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie this->get_service().set_option(this->get_implementation(), option, ec); 8000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::detail::throw_error(ec, "set_option"); 8010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 8020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 8030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Set an option on the socket. 8040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 8050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function is used to set an option on the socket. 8060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 8070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param option The new option value to be set on the socket. 8080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 8090ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param ec Set to indicate what error occurred, if any. 8100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 8110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @sa SettableSocketOption @n 8120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::broadcast @n 8130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::do_not_route @n 8140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::keep_alive @n 8150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::linger @n 8160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::receive_buffer_size @n 8170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::receive_low_watermark @n 8180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::reuse_address @n 8190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::send_buffer_size @n 8200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::send_low_watermark @n 8210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::multicast::join_group @n 8220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::multicast::leave_group @n 8230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::multicast::enable_loopback @n 8240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::multicast::outbound_interface @n 8250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::multicast::hops @n 8260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::no_delay 8270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 8280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @par Example 8290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * Setting the IPPROTO_TCP/TCP_NODELAY option: 8300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @code 8310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::socket socket(io_service); 8320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * ... 8330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::no_delay option(true); 8340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::error_code ec; 8350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * socket.set_option(option, ec); 8360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * if (ec) 8370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 8380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // An error occurred. 8390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * } 8400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @endcode 8410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 8420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie template <typename SettableSocketOption> 8430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code set_option(const SettableSocketOption& option, 8440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code& ec) 8450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 8460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return this->get_service().set_option( 8470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie this->get_implementation(), option, ec); 8480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 8490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 8500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Get an option from the socket. 8510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 8520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function is used to get the current value of an option on the socket. 8530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 8540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param option The option value to be obtained from the socket. 8550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 8560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @throws asio::system_error Thrown on failure. 8570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 8580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @sa GettableSocketOption @n 8590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::broadcast @n 8600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::do_not_route @n 8610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::keep_alive @n 8620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::linger @n 8630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::receive_buffer_size @n 8640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::receive_low_watermark @n 8650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::reuse_address @n 8660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::send_buffer_size @n 8670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::send_low_watermark @n 8680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::multicast::join_group @n 8690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::multicast::leave_group @n 8700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::multicast::enable_loopback @n 8710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::multicast::outbound_interface @n 8720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::multicast::hops @n 8730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::no_delay 8740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 8750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @par Example 8760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: 8770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @code 8780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::socket socket(io_service); 8790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * ... 8800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::socket::keep_alive option; 8810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * socket.get_option(option); 8820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * bool is_set = option.value(); 8830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @endcode 8840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 8850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie template <typename GettableSocketOption> 8860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie void get_option(GettableSocketOption& option) const 8870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 8880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code ec; 8890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie this->get_service().get_option(this->get_implementation(), option, ec); 8900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::detail::throw_error(ec, "get_option"); 8910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 8920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 8930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Get an option from the socket. 8940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 8950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function is used to get the current value of an option on the socket. 8960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 8970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param option The option value to be obtained from the socket. 8980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 8990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param ec Set to indicate what error occurred, if any. 9000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 9010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @sa GettableSocketOption @n 9020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::broadcast @n 9030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::do_not_route @n 9040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::keep_alive @n 9050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::linger @n 9060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::receive_buffer_size @n 9070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::receive_low_watermark @n 9080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::reuse_address @n 9090ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::send_buffer_size @n 9100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::send_low_watermark @n 9110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::multicast::join_group @n 9120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::multicast::leave_group @n 9130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::multicast::enable_loopback @n 9140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::multicast::outbound_interface @n 9150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::multicast::hops @n 9160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::no_delay 9170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 9180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @par Example 9190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * Getting the value of the SOL_SOCKET/SO_KEEPALIVE option: 9200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @code 9210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::socket socket(io_service); 9220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * ... 9230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::socket::keep_alive option; 9240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::error_code ec; 9250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * socket.get_option(option, ec); 9260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * if (ec) 9270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 9280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // An error occurred. 9290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * } 9300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * bool is_set = option.value(); 9310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @endcode 9320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 9330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie template <typename GettableSocketOption> 9340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code get_option(GettableSocketOption& option, 9350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code& ec) const 9360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 9370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return this->get_service().get_option( 9380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie this->get_implementation(), option, ec); 9390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 9400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 9410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Perform an IO control command on the socket. 9420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 9430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function is used to execute an IO control command on the socket. 9440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 9450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param command The IO control command to be performed on the socket. 9460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 9470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @throws asio::system_error Thrown on failure. 9480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 9490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @sa IoControlCommand @n 9500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::bytes_readable @n 9510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::non_blocking_io 9520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 9530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @par Example 9540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * Getting the number of bytes ready to read: 9550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @code 9560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::socket socket(io_service); 9570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * ... 9580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::socket::bytes_readable command; 9590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * socket.io_control(command); 9600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * std::size_t bytes_readable = command.get(); 9610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @endcode 9620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 9630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie template <typename IoControlCommand> 9640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie void io_control(IoControlCommand& command) 9650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 9660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code ec; 9670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie this->get_service().io_control(this->get_implementation(), command, ec); 9680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::detail::throw_error(ec, "io_control"); 9690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 9700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 9710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Perform an IO control command on the socket. 9720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 9730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function is used to execute an IO control command on the socket. 9740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 9750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param command The IO control command to be performed on the socket. 9760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 9770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param ec Set to indicate what error occurred, if any. 9780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 9790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @sa IoControlCommand @n 9800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::bytes_readable @n 9810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::socket_base::non_blocking_io 9820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 9830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @par Example 9840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * Getting the number of bytes ready to read: 9850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @code 9860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::socket socket(io_service); 9870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * ... 9880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::socket::bytes_readable command; 9890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::error_code ec; 9900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * socket.io_control(command, ec); 9910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * if (ec) 9920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 9930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // An error occurred. 9940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * } 9950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * std::size_t bytes_readable = command.get(); 9960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @endcode 9970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 9980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie template <typename IoControlCommand> 9990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code io_control(IoControlCommand& command, 10000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code& ec) 10010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 10020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return this->get_service().io_control( 10030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie this->get_implementation(), command, ec); 10040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 10050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 10060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Gets the non-blocking mode of the socket. 10070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 10080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @returns @c true if the socket's synchronous operations will fail with 10090ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::error::would_block if they are unable to perform the requested 10100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * operation immediately. If @c false, synchronous operations will block 10110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * until complete. 10120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 10130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @note The non-blocking mode has no effect on the behaviour of asynchronous 10140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * operations. Asynchronous operations will never fail with the error 10150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::error::would_block. 10160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 10170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie bool non_blocking() const 10180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 10190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return this->get_service().non_blocking(this->get_implementation()); 10200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 10210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 10220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Sets the non-blocking mode of the socket. 10230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 10240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param mode If @c true, the socket's synchronous operations will fail with 10250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::error::would_block if they are unable to perform the requested 10260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * operation immediately. If @c false, synchronous operations will block 10270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * until complete. 10280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 10290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @throws asio::system_error Thrown on failure. 10300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 10310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @note The non-blocking mode has no effect on the behaviour of asynchronous 10320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * operations. Asynchronous operations will never fail with the error 10330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::error::would_block. 10340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 10350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie void non_blocking(bool mode) 10360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 10370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code ec; 10380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie this->get_service().non_blocking(this->get_implementation(), mode, ec); 10390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::detail::throw_error(ec, "non_blocking"); 10400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 10410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 10420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Sets the non-blocking mode of the socket. 10430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 10440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param mode If @c true, the socket's synchronous operations will fail with 10450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::error::would_block if they are unable to perform the requested 10460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * operation immediately. If @c false, synchronous operations will block 10470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * until complete. 10480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 10490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param ec Set to indicate what error occurred, if any. 10500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 10510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @note The non-blocking mode has no effect on the behaviour of asynchronous 10520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * operations. Asynchronous operations will never fail with the error 10530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::error::would_block. 10540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 10550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code non_blocking( 10560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie bool mode, asio::error_code& ec) 10570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 10580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return this->get_service().non_blocking( 10590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie this->get_implementation(), mode, ec); 10600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 10610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 10620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Gets the non-blocking mode of the native socket implementation. 10630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 10640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function is used to retrieve the non-blocking mode of the underlying 10650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * native socket. This mode has no effect on the behaviour of the socket 10660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * object's synchronous operations. 10670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 10680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @returns @c true if the underlying socket is in non-blocking mode and 10690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * direct system calls may fail with asio::error::would_block (or the 10700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * equivalent system error). 10710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 10720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @note The current non-blocking mode is cached by the socket object. 10730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * Consequently, the return value may be incorrect if the non-blocking mode 10740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * was set directly on the native socket. 10750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 10760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @par Example 10770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function is intended to allow the encapsulation of arbitrary 10780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * non-blocking system calls as asynchronous operations, in a way that is 10790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * transparent to the user of the socket object. The following example 10800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * illustrates how Linux's @c sendfile system call might be encapsulated: 10810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @code template <typename Handler> 10820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * struct sendfile_op 10830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 10840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * tcp::socket& sock_; 10850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * int fd_; 10860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * Handler handler_; 10870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * off_t offset_; 10880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * std::size_t total_bytes_transferred_; 10890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 10900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // Function call operator meeting WriteHandler requirements. 10910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // Used as the handler for the async_write_some operation. 10920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * void operator()(asio::error_code ec, std::size_t) 10930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 10940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // Put the underlying socket into non-blocking mode. 10950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * if (!ec) 10960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * if (!sock_.native_non_blocking()) 10970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * sock_.native_non_blocking(true, ec); 10980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 10990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * if (!ec) 11000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 11010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * for (;;) 11020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 11030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // Try the system call. 11040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * errno = 0; 11050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); 11060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * ec = asio::error_code(n < 0 ? errno : 0, 11070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::error::get_system_category()); 11080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * total_bytes_transferred_ += ec ? 0 : n; 11090ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 11100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // Retry operation immediately if interrupted by signal. 11110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * if (ec == asio::error::interrupted) 11120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * continue; 11130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 11140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // Check if we need to run the operation again. 11150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * if (ec == asio::error::would_block 11160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * || ec == asio::error::try_again) 11170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 11180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // We have to wait for the socket to become ready again. 11190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * sock_.async_write_some(asio::null_buffers(), *this); 11200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * return; 11210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * } 11220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 11230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * if (ec || n == 0) 11240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 11250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // An error occurred, or we have reached the end of the file. 11260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // Either way we must exit the loop so we can call the handler. 11270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * break; 11280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * } 11290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 11300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // Loop around to try calling sendfile again. 11310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * } 11320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * } 11330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 11340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // Pass result back to user's handler. 11350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * handler_(ec, total_bytes_transferred_); 11360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * } 11370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * }; 11380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 11390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * template <typename Handler> 11400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * void async_sendfile(tcp::socket& sock, int fd, Handler h) 11410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 11420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * sendfile_op<Handler> op = { sock, fd, h, 0, 0 }; 11430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * sock.async_write_some(asio::null_buffers(), op); 11440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * } @endcode 11450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 11460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie bool native_non_blocking() const 11470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 11480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return this->get_service().native_non_blocking(this->get_implementation()); 11490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 11500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 11510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Sets the non-blocking mode of the native socket implementation. 11520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 11530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function is used to modify the non-blocking mode of the underlying 11540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * native socket. It has no effect on the behaviour of the socket object's 11550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * synchronous operations. 11560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 11570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param mode If @c true, the underlying socket is put into non-blocking 11580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * mode and direct system calls may fail with asio::error::would_block 11590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * (or the equivalent system error). 11600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 11610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @throws asio::system_error Thrown on failure. If the @c mode is 11620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @c false, but the current value of @c non_blocking() is @c true, this 11630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * function fails with asio::error::invalid_argument, as the 11640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * combination does not make sense. 11650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 11660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @par Example 11670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function is intended to allow the encapsulation of arbitrary 11680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * non-blocking system calls as asynchronous operations, in a way that is 11690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * transparent to the user of the socket object. The following example 11700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * illustrates how Linux's @c sendfile system call might be encapsulated: 11710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @code template <typename Handler> 11720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * struct sendfile_op 11730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 11740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * tcp::socket& sock_; 11750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * int fd_; 11760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * Handler handler_; 11770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * off_t offset_; 11780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * std::size_t total_bytes_transferred_; 11790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 11800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // Function call operator meeting WriteHandler requirements. 11810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // Used as the handler for the async_write_some operation. 11820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * void operator()(asio::error_code ec, std::size_t) 11830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 11840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // Put the underlying socket into non-blocking mode. 11850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * if (!ec) 11860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * if (!sock_.native_non_blocking()) 11870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * sock_.native_non_blocking(true, ec); 11880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 11890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * if (!ec) 11900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 11910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * for (;;) 11920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 11930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // Try the system call. 11940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * errno = 0; 11950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); 11960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * ec = asio::error_code(n < 0 ? errno : 0, 11970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::error::get_system_category()); 11980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * total_bytes_transferred_ += ec ? 0 : n; 11990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 12000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // Retry operation immediately if interrupted by signal. 12010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * if (ec == asio::error::interrupted) 12020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * continue; 12030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 12040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // Check if we need to run the operation again. 12050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * if (ec == asio::error::would_block 12060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * || ec == asio::error::try_again) 12070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 12080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // We have to wait for the socket to become ready again. 12090ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * sock_.async_write_some(asio::null_buffers(), *this); 12100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * return; 12110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * } 12120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 12130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * if (ec || n == 0) 12140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 12150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // An error occurred, or we have reached the end of the file. 12160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // Either way we must exit the loop so we can call the handler. 12170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * break; 12180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * } 12190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 12200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // Loop around to try calling sendfile again. 12210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * } 12220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * } 12230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 12240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // Pass result back to user's handler. 12250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * handler_(ec, total_bytes_transferred_); 12260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * } 12270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * }; 12280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 12290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * template <typename Handler> 12300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * void async_sendfile(tcp::socket& sock, int fd, Handler h) 12310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 12320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * sendfile_op<Handler> op = { sock, fd, h, 0, 0 }; 12330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * sock.async_write_some(asio::null_buffers(), op); 12340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * } @endcode 12350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 12360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie void native_non_blocking(bool mode) 12370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 12380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code ec; 12390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie this->get_service().native_non_blocking( 12400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie this->get_implementation(), mode, ec); 12410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::detail::throw_error(ec, "native_non_blocking"); 12420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 12430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 12440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Sets the non-blocking mode of the native socket implementation. 12450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 12460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function is used to modify the non-blocking mode of the underlying 12470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * native socket. It has no effect on the behaviour of the socket object's 12480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * synchronous operations. 12490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 12500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param mode If @c true, the underlying socket is put into non-blocking 12510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * mode and direct system calls may fail with asio::error::would_block 12520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * (or the equivalent system error). 12530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 12540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param ec Set to indicate what error occurred, if any. If the @c mode is 12550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @c false, but the current value of @c non_blocking() is @c true, this 12560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * function fails with asio::error::invalid_argument, as the 12570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * combination does not make sense. 12580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 12590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @par Example 12600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function is intended to allow the encapsulation of arbitrary 12610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * non-blocking system calls as asynchronous operations, in a way that is 12620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * transparent to the user of the socket object. The following example 12630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * illustrates how Linux's @c sendfile system call might be encapsulated: 12640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @code template <typename Handler> 12650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * struct sendfile_op 12660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 12670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * tcp::socket& sock_; 12680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * int fd_; 12690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * Handler handler_; 12700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * off_t offset_; 12710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * std::size_t total_bytes_transferred_; 12720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 12730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // Function call operator meeting WriteHandler requirements. 12740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // Used as the handler for the async_write_some operation. 12750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * void operator()(asio::error_code ec, std::size_t) 12760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 12770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // Put the underlying socket into non-blocking mode. 12780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * if (!ec) 12790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * if (!sock_.native_non_blocking()) 12800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * sock_.native_non_blocking(true, ec); 12810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 12820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * if (!ec) 12830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 12840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * for (;;) 12850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 12860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // Try the system call. 12870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * errno = 0; 12880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * int n = ::sendfile(sock_.native_handle(), fd_, &offset_, 65536); 12890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * ec = asio::error_code(n < 0 ? errno : 0, 12900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::error::get_system_category()); 12910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * total_bytes_transferred_ += ec ? 0 : n; 12920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 12930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // Retry operation immediately if interrupted by signal. 12940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * if (ec == asio::error::interrupted) 12950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * continue; 12960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 12970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // Check if we need to run the operation again. 12980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * if (ec == asio::error::would_block 12990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * || ec == asio::error::try_again) 13000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 13010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // We have to wait for the socket to become ready again. 13020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * sock_.async_write_some(asio::null_buffers(), *this); 13030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * return; 13040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * } 13050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 13060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * if (ec || n == 0) 13070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 13080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // An error occurred, or we have reached the end of the file. 13090ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // Either way we must exit the loop so we can call the handler. 13100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * break; 13110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * } 13120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 13130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // Loop around to try calling sendfile again. 13140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * } 13150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * } 13160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 13170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // Pass result back to user's handler. 13180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * handler_(ec, total_bytes_transferred_); 13190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * } 13200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * }; 13210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 13220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * template <typename Handler> 13230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * void async_sendfile(tcp::socket& sock, int fd, Handler h) 13240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 13250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * sendfile_op<Handler> op = { sock, fd, h, 0, 0 }; 13260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * sock.async_write_some(asio::null_buffers(), op); 13270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * } @endcode 13280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 13290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code native_non_blocking( 13300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie bool mode, asio::error_code& ec) 13310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 13320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return this->get_service().native_non_blocking( 13330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie this->get_implementation(), mode, ec); 13340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 13350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 13360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Get the local endpoint of the socket. 13370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 13380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function is used to obtain the locally bound endpoint of the socket. 13390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 13400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @returns An object that represents the local endpoint of the socket. 13410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 13420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @throws asio::system_error Thrown on failure. 13430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 13440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @par Example 13450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @code 13460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::socket socket(io_service); 13470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * ... 13480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::endpoint endpoint = socket.local_endpoint(); 13490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @endcode 13500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 13510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie endpoint_type local_endpoint() const 13520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 13530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code ec; 13540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie endpoint_type ep = this->get_service().local_endpoint( 13550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie this->get_implementation(), ec); 13560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::detail::throw_error(ec, "local_endpoint"); 13570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return ep; 13580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 13590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 13600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Get the local endpoint of the socket. 13610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 13620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function is used to obtain the locally bound endpoint of the socket. 13630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 13640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param ec Set to indicate what error occurred, if any. 13650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 13660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @returns An object that represents the local endpoint of the socket. 13670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * Returns a default-constructed endpoint object if an error occurred. 13680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 13690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @par Example 13700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @code 13710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::socket socket(io_service); 13720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * ... 13730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::error_code ec; 13740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::endpoint endpoint = socket.local_endpoint(ec); 13750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * if (ec) 13760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 13770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // An error occurred. 13780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * } 13790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @endcode 13800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 13810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie endpoint_type local_endpoint(asio::error_code& ec) const 13820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 13830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return this->get_service().local_endpoint(this->get_implementation(), ec); 13840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 13850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 13860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Get the remote endpoint of the socket. 13870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 13880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function is used to obtain the remote endpoint of the socket. 13890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 13900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @returns An object that represents the remote endpoint of the socket. 13910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 13920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @throws asio::system_error Thrown on failure. 13930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 13940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @par Example 13950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @code 13960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::socket socket(io_service); 13970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * ... 13980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(); 13990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @endcode 14000ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 14010ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie endpoint_type remote_endpoint() const 14020ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 14030ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code ec; 14040ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie endpoint_type ep = this->get_service().remote_endpoint( 14050ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie this->get_implementation(), ec); 14060ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::detail::throw_error(ec, "remote_endpoint"); 14070ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return ep; 14080ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 14090ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 14100ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Get the remote endpoint of the socket. 14110ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 14120ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function is used to obtain the remote endpoint of the socket. 14130ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 14140ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param ec Set to indicate what error occurred, if any. 14150ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 14160ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @returns An object that represents the remote endpoint of the socket. 14170ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * Returns a default-constructed endpoint object if an error occurred. 14180ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 14190ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @par Example 14200ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @code 14210ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::socket socket(io_service); 14220ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * ... 14230ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::error_code ec; 14240ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::endpoint endpoint = socket.remote_endpoint(ec); 14250ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * if (ec) 14260ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 14270ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // An error occurred. 14280ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * } 14290ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @endcode 14300ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 14310ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie endpoint_type remote_endpoint(asio::error_code& ec) const 14320ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 14330ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return this->get_service().remote_endpoint(this->get_implementation(), ec); 14340ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 14350ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 14360ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Disable sends or receives on the socket. 14370ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 14380ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function is used to disable send operations, receive operations, or 14390ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * both. 14400ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 14410ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param what Determines what types of operation will no longer be allowed. 14420ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 14430ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @throws asio::system_error Thrown on failure. 14440ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 14450ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @par Example 14460ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * Shutting down the send side of the socket: 14470ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @code 14480ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::socket socket(io_service); 14490ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * ... 14500ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * socket.shutdown(asio::ip::tcp::socket::shutdown_send); 14510ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @endcode 14520ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 14530ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie void shutdown(shutdown_type what) 14540ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 14550ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code ec; 14560ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie this->get_service().shutdown(this->get_implementation(), what, ec); 14570ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::detail::throw_error(ec, "shutdown"); 14580ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 14590ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 14600ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Disable sends or receives on the socket. 14610ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /** 14620ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * This function is used to disable send operations, receive operations, or 14630ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * both. 14640ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 14650ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param what Determines what types of operation will no longer be allowed. 14660ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 14670ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @param ec Set to indicate what error occurred, if any. 14680ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * 14690ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @par Example 14700ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * Shutting down the send side of the socket: 14710ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @code 14720ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::ip::tcp::socket socket(io_service); 14730ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * ... 14740ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * asio::error_code ec; 14750ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * socket.shutdown(asio::ip::tcp::socket::shutdown_send, ec); 14760ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * if (ec) 14770ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * { 14780ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * // An error occurred. 14790ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * } 14800ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie * @endcode 14810ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie */ 14820ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code shutdown(shutdown_type what, 14830ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie asio::error_code& ec) 14840ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 14850ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie return this->get_service().shutdown(this->get_implementation(), what, ec); 14860ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 14870ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 14880ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffieprotected: 14890ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie /// Protected destructor to prevent deletion through this type. 14900ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie ~basic_socket() 14910ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie { 14920ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie } 14930ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie}; 14940ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 14950ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie} // namespace asio 14960ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 14970ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#include "asio/detail/pop_options.hpp" 14980ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie 14990ee85db398be8ea33d67cc42f99a1468cd6c8180François Gaffie#endif // ASIO_BASIC_SOCKET_HPP 1500