Added support for setting certain socket options.
This commit is contained in:
parent
06e1a32187
commit
22237b0950
17
asio/TODO
17
asio/TODO
@ -1,12 +1,17 @@
|
||||
asio to-do items
|
||||
================
|
||||
|
||||
Add functions for setting socket options
|
||||
----------------------------------------
|
||||
Add functions to the basic_stream_socket and basic_dgram_socket that allow the
|
||||
various socket options to be set. May want to consider not exposing the option
|
||||
for non-blocking I/O, and simply state that using the asynchronous operations
|
||||
is the portable way to go about it.
|
||||
Add more socket options
|
||||
-----------------------
|
||||
Add support for additional socket options beyond the sample few that exist now.
|
||||
May want to consider not exposing the option for non-blocking I/O, and simply
|
||||
state that using the asynchronous operations is the portable way to go about
|
||||
it.
|
||||
|
||||
Add vectored send/recv functions
|
||||
--------------------------------
|
||||
Add the sendv and recvv functions to basic_stream_socket and presumably also to
|
||||
the buffered stream templates.
|
||||
|
||||
Add encode_send/async_encode_send functions
|
||||
-------------------------------------------
|
||||
|
@ -62,6 +62,7 @@ nobase_include_HEADERS = \
|
||||
asio/socket_acceptor.hpp \
|
||||
asio/socket_connector.hpp \
|
||||
asio/socket_error.hpp \
|
||||
asio/socket_option.hpp \
|
||||
asio/stream_socket.hpp \
|
||||
asio/timer.hpp \
|
||||
asio/timer_base.hpp
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "asio/socket_acceptor.hpp"
|
||||
#include "asio/socket_connector.hpp"
|
||||
#include "asio/socket_error.hpp"
|
||||
#include "asio/socket_option.hpp"
|
||||
#include "asio/stream_socket.hpp"
|
||||
#include "asio/timer.hpp"
|
||||
#include "asio/timer_base.hpp"
|
||||
|
@ -138,6 +138,34 @@ public:
|
||||
return impl_;
|
||||
}
|
||||
|
||||
/// Set an option on the socket.
|
||||
/**
|
||||
* This function is used to set an option on the socket.
|
||||
*
|
||||
* @param option The new option value to be set on the socket.
|
||||
*
|
||||
* @throws socket_error Thrown on failure.
|
||||
*/
|
||||
template <typename Option>
|
||||
void set_option(const Option& option)
|
||||
{
|
||||
service_.set_option(impl_, option);
|
||||
}
|
||||
|
||||
/// Get an option from the socket.
|
||||
/**
|
||||
* This function is used to get the current value of an option on the socket.
|
||||
*
|
||||
* @param option The option value to be obtained from the socket.
|
||||
*
|
||||
* @throws socket_error Thrown on failure.
|
||||
*/
|
||||
template <typename Option>
|
||||
void get_option(Option& option)
|
||||
{
|
||||
service_.get_option(impl_, option);
|
||||
}
|
||||
|
||||
/// Send a datagram to the specified address.
|
||||
/**
|
||||
* This function is used to send a datagram to the specified remote address.
|
||||
|
@ -184,6 +184,34 @@ public:
|
||||
return impl_;
|
||||
}
|
||||
|
||||
/// Set an option on the acceptor.
|
||||
/**
|
||||
* This function is used to set an option on the socket.
|
||||
*
|
||||
* @param option The new option value to be set on the socket.
|
||||
*
|
||||
* @throws socket_error Thrown on failure.
|
||||
*/
|
||||
template <typename Option>
|
||||
void set_option(const Option& option)
|
||||
{
|
||||
service_.set_option(impl_, option);
|
||||
}
|
||||
|
||||
/// Get an option from the acceptor.
|
||||
/**
|
||||
* This function is used to get the current value of an option on the socket.
|
||||
*
|
||||
* @param option The option value to be obtained from the socket.
|
||||
*
|
||||
* @throws socket_error Thrown on failure.
|
||||
*/
|
||||
template <typename Option>
|
||||
void get_option(Option& option)
|
||||
{
|
||||
service_.get_option(impl_, option);
|
||||
}
|
||||
|
||||
/// Accept a new connection.
|
||||
/**
|
||||
* This function is used to accept a new connection from a peer into the
|
||||
|
@ -128,6 +128,34 @@ public:
|
||||
service_.create(impl_, new_impl);
|
||||
}
|
||||
|
||||
/// Set an option on the socket.
|
||||
/**
|
||||
* This function is used to set an option on the socket.
|
||||
*
|
||||
* @param option The new option value to be set on the socket.
|
||||
*
|
||||
* @throws socket_error Thrown on failure.
|
||||
*/
|
||||
template <typename Option>
|
||||
void set_option(const Option& option)
|
||||
{
|
||||
service_.set_option(impl_, option);
|
||||
}
|
||||
|
||||
/// Get an option from the socket.
|
||||
/**
|
||||
* This function is used to get the current value of an option on the socket.
|
||||
*
|
||||
* @param option The option value to be obtained from the socket.
|
||||
*
|
||||
* @throws socket_error Thrown on failure.
|
||||
*/
|
||||
template <typename Option>
|
||||
void get_option(Option& option)
|
||||
{
|
||||
service_.get_option(impl_, option);
|
||||
}
|
||||
|
||||
/// Send the given data to the peer.
|
||||
/**
|
||||
* This function is used to send data to the stream socket's peer. The
|
||||
|
@ -22,7 +22,7 @@
|
||||
namespace asio {
|
||||
|
||||
/// The counting_completion_context class is a concrete implementation of the
|
||||
/// completion_context class that allows a limitation on the number of
|
||||
/// Completion_Context concept. It allows a limitation on the number of
|
||||
/// concurrent upcalls to completion handlers that may be associated with the
|
||||
/// context.
|
||||
class counting_completion_context
|
||||
|
@ -87,6 +87,25 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// Set a socket option. Throws a socket_error exception on failure.
|
||||
template <typename Option>
|
||||
void set_option(impl_type& impl, const Option& option)
|
||||
{
|
||||
if (socket_ops::setsockopt(impl, option.level(), option.name(),
|
||||
option.data(), option.size()))
|
||||
throw socket_error(socket_ops::get_error());
|
||||
}
|
||||
|
||||
// Set a socket option. Throws a socket_error exception on failure.
|
||||
template <typename Option>
|
||||
void get_option(impl_type& impl, Option& option)
|
||||
{
|
||||
socket_len_type size = option.size();
|
||||
if (socket_ops::getsockopt(impl, option.level(), option.name(),
|
||||
option.data(), &size))
|
||||
throw socket_error(socket_ops::get_error());
|
||||
}
|
||||
|
||||
// Send a datagram to the specified address. Returns the number of bytes
|
||||
// sent. Throws a socket_error exception on failure.
|
||||
template <typename Address>
|
||||
|
@ -98,6 +98,25 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// Set a socket option. Throws a socket_error exception on failure.
|
||||
template <typename Option>
|
||||
void set_option(impl_type& impl, const Option& option)
|
||||
{
|
||||
if (socket_ops::setsockopt(impl, option.level(), option.name(),
|
||||
option.data(), option.size()))
|
||||
throw socket_error(socket_ops::get_error());
|
||||
}
|
||||
|
||||
// Set a socket option. Throws a socket_error exception on failure.
|
||||
template <typename Option>
|
||||
void get_option(impl_type& impl, Option& option)
|
||||
{
|
||||
socket_len_type size = option.size();
|
||||
if (socket_ops::getsockopt(impl, option.level(), option.name(),
|
||||
option.data(), &size))
|
||||
throw socket_error(socket_ops::get_error());
|
||||
}
|
||||
|
||||
// Accept a new connection. Throws a socket_error exception on failure.
|
||||
template <typename Stream_Socket_Service>
|
||||
void accept(impl_type& impl,
|
||||
|
@ -72,6 +72,25 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// Set a socket option. Throws a socket_error exception on failure.
|
||||
template <typename Option>
|
||||
void set_option(impl_type& impl, const Option& option)
|
||||
{
|
||||
if (socket_ops::setsockopt(impl, option.level(), option.name(),
|
||||
option.data(), option.size()))
|
||||
throw socket_error(socket_ops::get_error());
|
||||
}
|
||||
|
||||
// Set a socket option. Throws a socket_error exception on failure.
|
||||
template <typename Option>
|
||||
void get_option(impl_type& impl, Option& option)
|
||||
{
|
||||
socket_len_type size = option.size();
|
||||
if (socket_ops::getsockopt(impl, option.level(), option.name(),
|
||||
option.data(), &size))
|
||||
throw socket_error(socket_ops::get_error());
|
||||
}
|
||||
|
||||
// Send the given data to the peer. Returns the number of bytes sent or
|
||||
// 0 if the connection was closed cleanly. Throws a socket_error exception
|
||||
// on failure.
|
||||
|
@ -94,6 +94,25 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// Set a socket option. Throws a socket_error exception on failure.
|
||||
template <typename Option>
|
||||
void set_option(impl_type& impl, const Option& option)
|
||||
{
|
||||
if (socket_ops::setsockopt(impl, option.level(), option.name(),
|
||||
option.data(), option.size()))
|
||||
throw socket_error(socket_ops::get_error());
|
||||
}
|
||||
|
||||
// Set a socket option. Throws a socket_error exception on failure.
|
||||
template <typename Option>
|
||||
void get_option(impl_type& impl, Option& option)
|
||||
{
|
||||
socket_len_type size = option.size();
|
||||
if (socket_ops::getsockopt(impl, option.level(), option.name(),
|
||||
option.data(), &size))
|
||||
throw socket_error(socket_ops::get_error());
|
||||
}
|
||||
|
||||
// Send a datagram to the specified address. Returns the number of bytes
|
||||
// sent. Throws a socket_error exception on failure.
|
||||
template <typename Address>
|
||||
|
@ -78,6 +78,25 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// Set a socket option. Throws a socket_error exception on failure.
|
||||
template <typename Option>
|
||||
void set_option(impl_type& impl, const Option& option)
|
||||
{
|
||||
if (socket_ops::setsockopt(impl, option.level(), option.name(),
|
||||
option.data(), option.size()))
|
||||
throw socket_error(socket_ops::get_error());
|
||||
}
|
||||
|
||||
// Set a socket option. Throws a socket_error exception on failure.
|
||||
template <typename Option>
|
||||
void get_option(impl_type& impl, Option& option)
|
||||
{
|
||||
socket_len_type size = option.size();
|
||||
if (socket_ops::getsockopt(impl, option.level(), option.name(),
|
||||
option.data(), &size))
|
||||
throw socket_error(socket_ops::get_error());
|
||||
}
|
||||
|
||||
// Send the given data to the peer. Returns the number of bytes sent or
|
||||
// 0 if the connection was closed cleanly. Throws a socket_error exception
|
||||
// on failure.
|
||||
|
@ -36,10 +36,10 @@ namespace detail
|
||||
template <typename Type> Type global<Type>::instance;
|
||||
}
|
||||
|
||||
/// The completion_context class is the abstract base class for all completion
|
||||
/// context implementations. A completion context is used to determine when
|
||||
/// an upcall can be made to the completion handler of an asynchronous
|
||||
/// operation.
|
||||
/// The null_completion_context class is a concrete implementation of the
|
||||
/// Completion_Context concept. It does not place any limits on the number of
|
||||
/// concurrent upcalls to completion handlers that may be associated with the
|
||||
/// context.
|
||||
class null_completion_context
|
||||
: private boost::noncopyable
|
||||
{
|
||||
|
167
asio/include/asio/socket_option.hpp
Normal file
167
asio/include/asio/socket_option.hpp
Normal file
@ -0,0 +1,167 @@
|
||||
//
|
||||
// socket_option.hpp
|
||||
// ~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
// Copyright (c) 2003 Christopher M. Kohlhoff (chris@kohlhoff.com)
|
||||
//
|
||||
// Permission to use, copy, modify, distribute and sell this software and its
|
||||
// documentation for any purpose is hereby granted without fee, provided that
|
||||
// the above copyright notice appears in all copies and that both the copyright
|
||||
// notice and this permission notice appear in supporting documentation. This
|
||||
// software is provided "as is" without express or implied warranty, and with
|
||||
// no claim as to its suitability for any purpose.
|
||||
//
|
||||
|
||||
#ifndef ASIO_SOCKET_OPTION_HPP
|
||||
#define ASIO_SOCKET_OPTION_HPP
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/socket_types.hpp"
|
||||
|
||||
namespace asio {
|
||||
namespace socket_option {
|
||||
|
||||
/// Helper template for implementing flag-based options.
|
||||
template <int Level, int Name>
|
||||
class flag
|
||||
{
|
||||
public:
|
||||
/// Default constructor.
|
||||
flag()
|
||||
: value_(0)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct to be either enabled or disabled.
|
||||
flag(bool enabled)
|
||||
: value_(enabled ? 1 : 0)
|
||||
{
|
||||
}
|
||||
|
||||
/// Get the level of the socket option.
|
||||
int level() const
|
||||
{
|
||||
return Level;
|
||||
}
|
||||
|
||||
/// Get the name of the socket option.
|
||||
int name() const
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
|
||||
/// Set the value of the flag.
|
||||
void set(bool enabled)
|
||||
{
|
||||
value_ = enabled ? 1 : 0;
|
||||
}
|
||||
|
||||
/// Get the current value of the flag.
|
||||
bool get() const
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
|
||||
/// Get the address of the flag data.
|
||||
void* data()
|
||||
{
|
||||
return &value_;
|
||||
}
|
||||
|
||||
/// Get the address of the flag data.
|
||||
const void* data() const
|
||||
{
|
||||
return &value_;
|
||||
}
|
||||
|
||||
/// Get the size of the flag data.
|
||||
size_t size() const
|
||||
{
|
||||
return sizeof(value_);
|
||||
}
|
||||
|
||||
private:
|
||||
/// The underlying value of the flag.
|
||||
int value_;
|
||||
};
|
||||
|
||||
/// Helper template for implementing integer options.
|
||||
template <int Level, int Name>
|
||||
class integer
|
||||
{
|
||||
public:
|
||||
/// Default constructor.
|
||||
integer()
|
||||
: value_(0)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct with a specific option value.
|
||||
integer(int value)
|
||||
: value_(value)
|
||||
{
|
||||
}
|
||||
|
||||
/// Get the level of the socket option.
|
||||
int level() const
|
||||
{
|
||||
return Level;
|
||||
}
|
||||
|
||||
/// Get the name of the socket option.
|
||||
int name() const
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
|
||||
/// Set the value of the int option.
|
||||
void set(int value)
|
||||
{
|
||||
value_ = value;
|
||||
}
|
||||
|
||||
/// Get the current value of the int option.
|
||||
int get() const
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
|
||||
/// Get the address of the int data.
|
||||
void* data()
|
||||
{
|
||||
return &value_;
|
||||
}
|
||||
|
||||
/// Get the address of the int data.
|
||||
const void* data() const
|
||||
{
|
||||
return &value_;
|
||||
}
|
||||
|
||||
/// Get the size of the int data.
|
||||
size_t size() const
|
||||
{
|
||||
return sizeof(value_);
|
||||
}
|
||||
|
||||
private:
|
||||
/// The underlying value of the int option.
|
||||
int value_;
|
||||
};
|
||||
|
||||
/// Permit sending of broadcast datagrams.
|
||||
typedef flag<IPPROTO_TCP, TCP_NODELAY> tcp_no_delay;
|
||||
|
||||
/// The receive buffer size for a socket.
|
||||
typedef integer<SOL_SOCKET, SO_SNDBUF> send_buffer_size;
|
||||
|
||||
/// The send buffer size for a socket.
|
||||
typedef integer<SOL_SOCKET, SO_RCVBUF> recv_buffer_size;
|
||||
|
||||
} // namespace socket_option
|
||||
} // namespace asio
|
||||
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#endif // ASIO_SOCKET_OPTION_HPP
|
@ -3,6 +3,11 @@
|
||||
\brief The asio namespace defines all user-accessible classes and templates.
|
||||
*/
|
||||
|
||||
/**
|
||||
\namespace asio::socket_option
|
||||
\brief The asio::socket_option namespace defines the supported socket options.
|
||||
*/
|
||||
|
||||
/**
|
||||
\mainpage
|
||||
|
||||
@ -13,6 +18,7 @@
|
||||
<H2>Namespaces</H2>
|
||||
|
||||
\li ::asio
|
||||
\li ::asio::socket_option
|
||||
|
||||
<H2>Core Classes</H2>
|
||||
|
||||
|
@ -12,9 +12,12 @@ void tpc_echo_session(stream_socket_ptr sock)
|
||||
{
|
||||
try
|
||||
{
|
||||
enum { max_length = 512 };
|
||||
enum { max_length = 8192 };
|
||||
char data[max_length];
|
||||
|
||||
sock->set_option(socket_option::recv_buffer_size(max_length));
|
||||
sock->set_option(socket_option::send_buffer_size(max_length));
|
||||
|
||||
int length;
|
||||
while ((length = recv(*sock, data, max_length)) > 0)
|
||||
if (send_n(*sock, data, length) <= 0)
|
||||
|
Loading…
Reference in New Issue
Block a user