Added support for setting certain socket options.

This commit is contained in:
chris 2003-11-10 02:52:32 +00:00
parent 06e1a32187
commit 22237b0950
16 changed files with 374 additions and 12 deletions

View File

@ -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
-------------------------------------------

View File

@ -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

View File

@ -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"

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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,

View File

@ -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.

View File

@ -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>

View File

@ -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.

View File

@ -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
{

View 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

View File

@ -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>

View File

@ -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)