Move inet_address_v4 to ipv4::address and add support for specifying the

protocol.
This commit is contained in:
chris 2004-01-12 07:01:21 +00:00
parent 795fd7b714
commit d76d1f4cc8
34 changed files with 562 additions and 252 deletions

View File

@ -55,7 +55,9 @@ nobase_include_HEADERS = \
asio/dgram_socket.hpp \
asio/error_handler.hpp \
asio/fixed_buffer.hpp \
asio/inet_address_v4.hpp \
asio/ipv4/address.hpp \
asio/ipv4/tcp.hpp \
asio/ipv4/udp.hpp \
asio/null_completion_context.hpp \
asio/recv.hpp \
asio/send.hpp \

View File

@ -29,7 +29,9 @@
#include "asio/dgram_socket.hpp"
#include "asio/error_handler.hpp"
#include "asio/fixed_buffer.hpp"
#include "asio/inet_address_v4.hpp"
#include "asio/ipv4/address.hpp"
#include "asio/ipv4/tcp.hpp"
#include "asio/ipv4/udp.hpp"
#include "asio/null_completion_context.hpp"
#include "asio/recv.hpp"
#include "asio/send.hpp"

View File

@ -58,10 +58,13 @@ public:
{
}
/// Construct a basic_dgram_socket opened on the given address.
/// Construct a basic_dgram_socket, opening it and binding it to the given
/// local address.
/**
* This constructor creates a dgram socket and automatically opens it bound
* to the specified address on the local machine.
* to the specified address on the local machine. The protocol is determined
* automatically to be the default datagram protocol associated with the
* given address type.
*
* @param d The demuxer object that the dgram socket will use to deliver
* completions for any asynchronous operations performed on the socket.
@ -76,40 +79,15 @@ public:
: service_(d.get_service(service_factory<Service>())),
impl_(service_type::null())
{
service_.create(impl_, address, default_error_handler());
}
/// Construct a basic_dgram_socket opened on the given address.
/**
* This constructor creates a dgram socket and automatically opens it bound
* to the specified address on the local machine.
*
* @param d The demuxer object that the dgram socket will use to deliver
* completions for any asynchronous operations performed on the socket.
*
* @param address An address on the local machine to which the dgram socket
* will be bound.
*
* @param error_handler The handler to be called when an error occurs. Copies
* will be made of the handler as required. The equivalent function signature
* of the handler must be:
* @code void error_handler(
* const asio::socket_error& error // Result of operation
* ); @endcode
*/
template <typename Address, typename Error_Handler>
basic_dgram_socket(demuxer_type& d, const Address& address,
Error_Handler error_handler)
: service_(d.get_service(service_factory<Service>())),
impl_(service_type::null())
{
service_.create(impl_, address, error_handler);
typedef typename Address::default_dgram_protocol default_protocol;
service_.open(impl_, default_protocol(), default_error_handler());
service_.bind(impl_, address, default_error_handler());
}
/// Destructor.
~basic_dgram_socket()
{
service_.destroy(impl_);
service_.close(impl_);
}
/// Get the demuxer associated with the asynchronous object.
@ -126,10 +104,45 @@ public:
return service_.demuxer();
}
/// Open the socket on the given address.
/// Open the socket using the specified protocol.
/**
* This function opens the dgram socket so that it is bound to the specified
* address on the local machine.
* This function opens the dgram socket so that it will use the specified
* protocol.
*
* @param protocol An object specifying which protocol is to be used.
*
* @throws socket_error Thrown on failure.
*/
template <typename Protocol>
void open(const Protocol& protocol)
{
service_.open(impl_, protocol, default_error_handler());
}
/// Open the socket using the specified protocol.
/**
* This function opens the dgram socket so that it will use the specified
* protocol.
*
* @param protocol An object specifying which protocol is to be used.
*
* @param error_handler The handler to be called when an error occurs. Copies
* will be made of the handler as required. The equivalent function signature
* of the handler must be:
* @code void error_handler(
* const asio::socket_error& error // Result of operation
* ); @endcode
*/
template <typename Protocol, typename Error_Handler>
void open(const Protocol& protocol, Error_Handler error_handler)
{
service_.open(impl_, protocol, error_handler);
}
/// Bind the socket to the given local address.
/**
* This function binds the dgram socket to the specified address on the local
* machine.
*
* @param address An address on the local machine to which the dgram socket
* will be bound.
@ -137,15 +150,15 @@ public:
* @throws socket_error Thrown on failure.
*/
template <typename Address>
void open(const Address& address)
void bind(const Address& address)
{
service_.create(impl_, address, default_error_handler());
service_.bind(impl_, address, default_error_handler());
}
/// Open the socket on the given address.
/// Bind the socket to the given local address.
/**
* This function opens the dgram socket so that it is bound to the specified
* address on the local machine.
* This function binds the dgram socket to the specified address on the local
* machine.
*
* @param address An address on the local machine to which the dgram socket
* will be bound.
@ -158,9 +171,9 @@ public:
* ); @endcode
*/
template <typename Address, typename Error_Handler>
void open(const Address& address, Error_Handler error_handler)
void bind(const Address& address, Error_Handler error_handler)
{
service_.create(impl_, address, error_handler);
service_.bind(impl_, address, error_handler);
}
/// Close the socket.
@ -173,7 +186,7 @@ public:
*/
void close()
{
service_.destroy(impl_);
service_.close(impl_);
}
/// Get the underlying implementation in the native type.

View File

@ -69,54 +69,27 @@ public:
* @param addr An address on the local machine on which the acceptor will
* listen for new connections.
*
* @param listen_queue The maximum length of the queue of pending
* @param listen_backlog The maximum length of the queue of pending
* connections. A value of 0 means use the default queue length.
*
* @throws socket_error Thrown on failure.
*/
template <typename Address>
basic_socket_acceptor(demuxer_type& d, const Address& addr,
int listen_queue = 0)
basic_socket_acceptor(demuxer_type& d, const Address& address,
int listen_backlog = 0)
: service_(d.get_service(service_factory<Service>())),
impl_(service_type::null())
{
service_.create(impl_, addr, listen_queue, default_error_handler());
}
/// Construct an acceptor opened on the given address.
/**
* This constructor creates an acceptor and automatically opens it to listen
* for new connections on the specified address.
*
* @param d The demuxer object that the acceptor will use to deliver
* completions for any asynchronous operations performed on the acceptor.
*
* @param addr An address on the local machine on which the acceptor will
* listen for new connections.
*
* @param listen_queue The maximum length of the queue of pending
* connections. A value of 0 means use the default queue length.
*
* @param error_handler The handler to be called when an error occurs. Copies
* will be made of the handler as required. The equivalent function signature
* of the handler must be:
* @code void error_handler(
* const asio::socket_error& error // Result of operation
* ); @endcode
*/
template <typename Address, typename Error_Handler>
basic_socket_acceptor(demuxer_type& d, const Address& addr, int listen_queue,
Error_Handler error_handler)
: service_(d.get_service(service_factory<Service>())),
impl_(service_type::null())
{
service_.create(impl_, addr, listen_queue, error_handler);
typedef typename Address::default_stream_protocol default_protocol;
service_.open(impl_, default_protocol(), default_error_handler());
service_.bind(impl_, address, default_error_handler());
service_.listen(impl_, listen_backlog, default_error_handler());
}
/// Destructor.
~basic_socket_acceptor()
{
service_.destroy(impl_);
service_.close(impl_);
}
/// Get the demuxer associated with the asynchronous object.
@ -133,35 +106,62 @@ public:
return service_.demuxer();
}
/// Open the acceptor using the given address.
/// Open the acceptor using the specified protocol.
/**
* This function opens the acceptor to listen for new connections on the
* specified address.
* This function opens the socket acceptor so that it will use the specified
* protocol.
*
* @param addr An address on the local machine on which the acceptor will
* listen for new connections.
* @param protocol An object specifying which protocol is to be used.
*/
template <typename Protocol>
void open(const Protocol& protocol)
{
service_.open(impl_, protocol, default_error_handler());
}
/// Open the acceptor using the specified protocol.
/**
* This function opens the socket acceptor so that it will use the specified
* protocol.
*
* @param listen_queue The maximum length of the queue of pending
* connections. A value of 0 means use the default queue length.
* @param protocol An object specifying which protocol is to be used.
*
* @param error_handler The handler to be called when an error occurs. Copies
* will be made of the handler as required. The equivalent function signature
* of the handler must be:
* @code void error_handler(
* const asio::socket_error& error // Result of operation
* ); @endcode
*/
template <typename Protocol, typename Error_Handler>
void open(const Protocol& protocol, Error_Handler error_handler)
{
service_.open(impl_, protocol, error_handler);
}
/// Bind the acceptor to the given local address.
/**
* This function binds the socket acceptor to the specified address on the
* local machine.
*
* @param address An address on the local machine to which the socket
* acceptor will be bound.
*
* @throws socket_error Thrown on failure.
*/
template <typename Address>
void open(const Address& addr, int listen_queue = 0)
void bind(const Address& address)
{
service_.create(impl_, addr, listen_queue, default_error_handler());
service_.bind(impl_, address, default_error_handler());
}
/// Open the acceptor using the given address.
/// Bind the acceptor to the given local address.
/**
* This function opens the acceptor to listen for new connections on the
* specified address.
* This function binds the socket acceptor to the specified address on the
* local machine.
*
* @param addr An address on the local machine on which the acceptor will
* listen for new connections.
*
* @param listen_queue The maximum length of the queue of pending
* connections. A value of 0 means use the default queue length.
* @param address An address on the local machine to which the socket
* acceptor will be bound.
*
* @param error_handler The handler to be called when an error occurs. Copies
* will be made of the handler as required. The equivalent function signature
@ -171,9 +171,45 @@ public:
* ); @endcode
*/
template <typename Address, typename Error_Handler>
void open(const Address& addr, int listen_queue, Error_Handler error_handler)
void bind(const Address& address, Error_Handler error_handler)
{
service_.create(impl_, addr, listen_queue, error_handler);
service_.bind(impl_, address, error_handler);
}
/// Place the acceptor into the state where it will listen for new
/// connections.
/**
* This function puts the socket acceptor into the state where it may accept
* new connections.
*
* @param backlog The maximum length of the queue of pending connections. A
* value of 0 means use the default queue length.
*/
void listen(int backlog = 0)
{
service_.listen(impl_, backlog, default_error_handler());
}
/// Place the acceptor into the state where it will listen for new
/// connections.
/**
* This function puts the socket acceptor into the state where it may accept
* new connections.
*
* @param backlog The maximum length of the queue of pending connections. A
* value of 0 means use the default queue length.
*
* @param error_handler The handler to be called when an error occurs. Copies
* will be made of the handler as required. The equivalent function signature
* of the handler must be:
* @code void error_handler(
* const asio::socket_error& error // Result of operation
* ); @endcode
*/
template <typename Error_Handler>
void listen(int backlog, Error_Handler error_handler)
{
service_.listen(impl_, backlog, error_handler);
}
/// Close the acceptor.
@ -186,7 +222,7 @@ public:
*/
void close()
{
service_.destroy(impl_);
service_.close(impl_);
}
/// Get the underlying implementation in the native type.

View File

@ -45,7 +45,7 @@ public:
/// Constructor.
/**
* This constructor automatically opens the connector.
* Constructs the connector and opens it automatically.
*
* @param d The demuxer object that the connector will use to deliver
* completions for any asynchronous operations performed on the connector.
@ -54,13 +54,32 @@ public:
: service_(d.get_service(service_factory<Service>())),
impl_(service_type::null())
{
service_.create(impl_);
service_.open(impl_);
}
/// Constructor.
/**
* This constructor automatically opens the connector so that it will
* establish connections using the specified protocol.
*
* @param d The demuxer object that the connector will use to deliver
* completions for any asynchronous operations performed on the connector.
*
* @param protocol The protocol to be used for all new connections
* established using the connector.
*/
template <typename Protocol>
basic_socket_connector(demuxer_type& d, const Protocol& protocol)
: service_(d.get_service(service_factory<Service>())),
impl_(service_type::null())
{
service_.open(impl_, protocol);
}
/// Destructor.
~basic_socket_connector()
{
service_.destroy(impl_);
service_.close(impl_);
}
/// Get the demuxer associated with the asynchronous object.
@ -89,7 +108,26 @@ public:
*/
void open()
{
service_.create(impl_);
service_.open(impl_);
}
/// Open the connector to use a specified protocol.
/**
* This function is used to open the connector so that it may be used to
* perform socket connect operations.
*
* Since the constructor opens the connector by default, you should only need
* to call this function if there has been a prior call to close().
*
* @param protocol The protocol to be used for all new connections
* established using the connector.
*
* @throws socket_error Thrown on failure.
*/
template <typename Protocol>
void open(const Protocol& protocol)
{
service_.open(impl_, protocol);
}
/// Close the connector.
@ -102,7 +140,7 @@ public:
*/
void close()
{
service_.destroy(impl_);
service_.close(impl_);
}
/// Get the underlying implementation in the native type.

View File

@ -65,7 +65,7 @@ public:
/// Destructor.
~basic_stream_socket()
{
service_.destroy(impl_);
service_.close(impl_);
}
/// Get the demuxer associated with the asynchronous object.
@ -89,7 +89,7 @@ public:
*/
void close()
{
service_.destroy(impl_);
service_.close(impl_);
}
/// Get a reference to the lowest layer.
@ -126,7 +126,7 @@ public:
*/
void set_impl(impl_type new_impl)
{
service_.create(impl_, new_impl);
service_.open(impl_, new_impl);
}
/// Set an option on the socket.

View File

@ -57,34 +57,37 @@ public:
return demuxer_;
}
// Create a new dgram socket implementation.
template <typename Address, typename Error_Handler>
void create(impl_type& impl, const Address& address,
// Open a new dgram socket implementation.
template <typename Protocol, typename Error_Handler>
void open(impl_type& impl, const Protocol& protocol,
Error_Handler error_handler)
{
socket_holder sock(socket_ops::socket(address.family(), SOCK_DGRAM, 0));
if (protocol.type() != SOCK_DGRAM)
{
error_handler(socket_error(socket_error::invalid_argument));
return;
}
socket_holder sock(socket_ops::socket(protocol.family(), protocol.type(),
protocol.protocol()));
if (sock.get() == invalid_socket)
{
error_handler(socket_error(socket_ops::get_error()));
return;
}
else
impl = sock.release();
}
int reuse = 1;
socket_ops::setsockopt(sock.get(), SOL_SOCKET, SO_REUSEADDR, &reuse,
sizeof(reuse));
if (socket_ops::bind(sock.get(), address.native_address(),
// Bind the dgram socket to the specified local address.
template <typename Address, typename Error_Handler>
void bind(impl_type& impl, const Address& address,
Error_Handler error_handler)
{
if (socket_ops::bind(impl, address.native_address(),
address.native_size()) == socket_error_retval)
{
error_handler(socket_error(socket_ops::get_error()));
return;
}
impl = sock.release();
}
// Destroy a dgram socket implementation.
void destroy(impl_type& impl)
void close(impl_type& impl)
{
if (impl != null())
{

View File

@ -58,43 +58,43 @@ public:
return demuxer_;
}
// Create a new stream socket implementation.
template <typename Address, typename Error_Handler>
void create(impl_type& impl, const Address& address, int listen_queue,
// Open a new socket acceptor implementation.
template <typename Protocol, typename Error_Handler>
void open(impl_type& impl, const Protocol& protocol,
Error_Handler error_handler)
{
if (listen_queue == 0)
listen_queue = SOMAXCONN;
socket_holder sock(socket_ops::socket(address.family(), SOCK_STREAM, 0));
socket_holder sock(socket_ops::socket(protocol.family(), protocol.type(),
protocol.protocol()));
if (sock.get() == invalid_socket)
{
error_handler(socket_error(socket_ops::get_error()));
return;
}
int reuse = 1;
socket_ops::setsockopt(sock.get(), SOL_SOCKET, SO_REUSEADDR, &reuse,
sizeof(reuse));
if (socket_ops::bind(sock.get(), address.native_address(),
address.native_size()) == socket_error_retval)
{
error_handler(socket_error(socket_ops::get_error()));
return;
}
if (socket_ops::listen(sock.get(), listen_queue) == socket_error_retval)
{
error_handler(socket_error(socket_ops::get_error()));
return;
}
impl = sock.release();
else
impl = sock.release();
}
// Destroy a stream socket implementation.
void destroy(impl_type& impl)
// Bind the socket acceptor to the specified local address.
template <typename Address, typename Error_Handler>
void bind(impl_type& impl, const Address& address,
Error_Handler error_handler)
{
if (socket_ops::bind(impl, address.native_address(),
address.native_size()) == socket_error_retval)
error_handler(socket_error(socket_ops::get_error()));
}
// Place the socket acceptor into the state where it will listen for new
// connections.
template <typename Error_Handler>
void listen(impl_type& impl, int backlog, Error_Handler error_handler)
{
if (backlog == 0)
backlog = SOMAXCONN;
if (socket_ops::listen(impl, backlog) == socket_error_retval)
error_handler(socket_error(socket_ops::get_error()));
}
// Close a socket acceptor implementation.
void close(impl_type& impl)
{
if (impl != null())
{

View File

@ -43,6 +43,48 @@ public:
public:
typedef std::set<socket_type> socket_set;
// Default constructor.
connector_impl()
: have_protocol_(false),
family_(0),
type_(0),
protocol_(0)
{
}
// Construct to use a specific protocol.
connector_impl(int family, int type, int protocol)
: have_protocol_(true),
family_(family),
type_(type),
protocol_(protocol)
{
}
// Whether a protocol was specified.
bool have_protocol() const
{
return have_protocol_;
}
// Get the protocol family to use for new sockets.
int family() const
{
return family_;
}
// Get the type to use for new sockets.
int type() const
{
return type_;
}
// Get the protocol to use for new sockets.
int protocol() const
{
return protocol_;
}
// Add a socket to the set.
void add_socket(socket_type s)
{
@ -70,6 +112,18 @@ public:
// The sockets currently contained in the set.
socket_set sockets_;
// Whether a protocol has been specified.
bool have_protocol_;
// The protocol family to use for new sockets.
int family_;
// The type (e.g. SOCK_STREAM or SOCK_DGRAM) to use for new sockets.
int type_;
// The protocol to use for new sockets.
int protocol_;
};
// The native type of the socket connector. This type is dependent on the
@ -98,14 +152,23 @@ public:
return demuxer_;
}
// Create a new socket connector implementation.
void create(impl_type& impl)
// Open a new socket connector implementation without specifying a protocol.
void open(impl_type& impl)
{
impl = new connector_impl;
}
// Destroy a stream socket implementation.
void destroy(impl_type& impl)
// Open a new socket connector implementation so that it will create sockets
// using the specified protocol.
template <typename Protocol>
void open(impl_type& impl, const Protocol& protocol)
{
impl = new connector_impl(protocol.family(), protocol.type(),
protocol.protocol());
}
// Close a socket connector implementation.
void close(impl_type& impl)
{
if (impl != null())
{
@ -133,10 +196,23 @@ public:
return;
}
// Get the flags used to create the new socket.
typedef typename Address::default_stream_protocol protocol;
int family = impl->have_protocol() ? impl->family() : protocol().family();
int type = impl->have_protocol() ? impl->type() : protocol().type();
int proto = impl->have_protocol()
? impl->protocol() : protocol().protocol();
// We can only connect stream sockets.
if (type != SOCK_STREAM)
{
error_handler(socket_error(socket_error::invalid_argument));
return;
}
// Create a new socket for the connection. This will not be put into the
// stream_socket object until the connection has beenestablished.
socket_holder sock(socket_ops::socket(peer_address.family(), SOCK_STREAM,
0));
socket_holder sock(socket_ops::socket(family, type, proto));
if (sock.get() == invalid_socket)
{
error_handler(socket_error(socket_ops::get_error()));
@ -253,10 +329,24 @@ public:
return;
}
// Get the flags used to create the new socket.
typedef typename Address::default_stream_protocol protocol;
int family = impl->have_protocol() ? impl->family() : protocol().family();
int type = impl->have_protocol() ? impl->type() : protocol().type();
int proto = impl->have_protocol()
? impl->protocol() : protocol().protocol();
// We can only connect stream sockets.
if (type != SOCK_STREAM)
{
socket_error error(socket_error::invalid_argument);
demuxer_.operation_immediate(bind_handler(handler, error));
return;
}
// Create a new socket for the connection. This will not be put into the
// stream_socket object until the connection has beenestablished.
socket_holder new_socket(socket_ops::socket(peer_address.family(),
SOCK_STREAM, 0));
socket_holder new_socket(socket_ops::socket(family, type, proto));
if (new_socket.get() == invalid_socket)
{
socket_error error(socket_ops::get_error());

View File

@ -56,14 +56,14 @@ public:
return demuxer_;
}
// Create a new stream socket implementation.
void create(impl_type& impl, impl_type new_impl)
// Open a new stream socket implementation.
void open(impl_type& impl, impl_type new_impl)
{
impl = new_impl;
}
// Destroy a stream socket implementation.
void destroy(impl_type& impl)
void close(impl_type& impl)
{
if (impl != null())
{

View File

@ -62,25 +62,20 @@ public:
return demuxer_;
}
// Create a new dgram socket implementation.
template <typename Address, typename Error_Handler>
void create(impl_type& impl, const Address& address,
// Open a new dgram socket implementation.
template <typename Protocol, typename Error_Handler>
void open(impl_type& impl, const Protocol& protocol,
Error_Handler error_handler)
{
socket_holder sock(socket_ops::socket(address.family(), SOCK_DGRAM,
IPPROTO_UDP));
if (sock.get() == invalid_socket)
if (protocol.type() != SOCK_DGRAM)
{
error_handler(socket_error(socket_ops::get_error()));
error_handler(socket_error(socket_error::invalid_argument));
return;
}
int reuse = 1;
socket_ops::setsockopt(sock.get(), SOL_SOCKET, SO_REUSEADDR, &reuse,
sizeof(reuse));
if (socket_ops::bind(sock.get(), address.native_address(),
address.native_size()) == socket_error_retval)
socket_holder sock(socket_ops::socket(protocol.family(), protocol.type(),
protocol.protocol()));
if (sock.get() == invalid_socket)
{
error_handler(socket_error(socket_ops::get_error()));
return;
@ -91,8 +86,18 @@ public:
impl = sock.release();
}
// Bind the dgram socket to the specified local address.
template <typename Address, typename Error_Handler>
void bind(impl_type& impl, const Address& address,
Error_Handler error_handler)
{
if (socket_ops::bind(impl, address.native_address(),
address.native_size()) == socket_error_retval)
error_handler(socket_error(socket_ops::get_error()));
}
// Destroy a dgram socket implementation.
void destroy(impl_type& impl)
void close(impl_type& impl)
{
if (impl != null())
{

View File

@ -61,15 +61,15 @@ public:
return demuxer_;
}
// Create a new stream socket implementation.
void create(impl_type& impl, impl_type new_impl)
// Open a new stream socket implementation.
void open(impl_type& impl, impl_type new_impl)
{
demuxer_service_.register_socket(new_impl);
impl = new_impl;
}
// Destroy a stream socket implementation.
void destroy(impl_type& impl)
// Close a stream socket implementation.
void close(impl_type& impl)
{
if (impl != null())
{

View File

@ -1,6 +1,6 @@
//
// inet_address_v4.hpp
// ~~~~~~~~~~~~~~~~~~~
// address.hpp
// ~~~~~~~~~~~
//
// Copyright (c) 2003, 2004 Christopher M. Kohlhoff (chris@kohlhoff.com)
//
@ -12,8 +12,8 @@
// no claim as to its suitability for any purpose.
//
#ifndef ASIO_INET_ADDRESS_V4_HPP
#define ASIO_INET_ADDRESS_V4_HPP
#ifndef ASIO_IPV4_ADDRESS_HPP
#define ASIO_IPV4_ADDRESS_HPP
#include "asio/detail/push_options.hpp"
@ -25,13 +25,22 @@
#include "asio/socket_error.hpp"
#include "asio/detail/socket_types.hpp"
#include "asio/ipv4/tcp.hpp"
#include "asio/ipv4/udp.hpp"
namespace asio {
namespace ipv4 {
/// The inet_address_v4 class implements IP version 4 style addresses.
class inet_address_v4
/// The address class implements IP version 4 style addresses.
class address
{
public:
/// The default stream-based protocol associated with the address type.
typedef tcp default_stream_protocol;
/// The default datagram-based protocol associated with the address type.
typedef udp default_dgram_protocol;
/// The native types of the socket address. These types are dependent on the
/// underlying implementation of the socket layer.
typedef detail::socket_addr_type native_address_type;
@ -42,7 +51,7 @@ public:
typedef boost::uint_t<32>::least addr_type;
/// Default constructor.
inet_address_v4()
address()
{
addr_.sin_family = AF_INET;
addr_.sin_port = 0;
@ -52,7 +61,7 @@ public:
/// Construct an address using a port number, specified in the host's byte
/// order. The IP address will be the any address (i.e. INADDR_ANY). This
/// constructor would typically be used for accepting new connections.
inet_address_v4(port_type port_num)
address(port_type port_num)
{
addr_.sin_family = AF_INET;
addr_.sin_port = htons(port_num);
@ -62,7 +71,7 @@ public:
/// Construct an address using a port number and an IP address. This
/// constructor may be used for accepting connections on a specific interface
/// or for making a connection to a remote address.
inet_address_v4(port_type port_num, addr_type host_addr)
address(port_type port_num, addr_type host_addr)
{
addr_.sin_family = AF_INET;
addr_.sin_port = htons(port_num);
@ -73,7 +82,7 @@ public:
/// decimal form or a host name. This constructor may be used for accepting
/// connections on a specific interface or for making a connection to a
/// remote address.
inet_address_v4(port_type port_num, const std::string& host)
address(port_type port_num, const std::string& host)
{
addr_.sin_family = AF_INET;
addr_.sin_port = htons(port_num);
@ -81,13 +90,13 @@ public:
}
/// Copy constructor.
inet_address_v4(const inet_address_v4& other)
address(const address& other)
: addr_(other.addr_)
{
}
/// Assign from another inet_address_v4.
inet_address_v4& operator=(const inet_address_v4& other)
/// Assign from another address.
address& operator=(const address& other)
{
addr_ = other.addr_;
return *this;
@ -102,13 +111,13 @@ public:
/// Get the underlying address in the native type.
native_address_type* native_address()
{
return reinterpret_cast<inet_address_v4::native_address_type*>(&addr_);
return reinterpret_cast<address::native_address_type*>(&addr_);
}
/// Get the underlying address in the native type.
const native_address_type* native_address() const
{
return reinterpret_cast<const inet_address_v4::native_address_type*>(
return reinterpret_cast<const address::native_address_type*>(
&addr_);
}
@ -202,8 +211,9 @@ private:
detail::inet_addr_v4_type addr_;
};
} // namespace ipv4
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_INET_ADDRESS_V4_HPP
#endif // ASIO_IPV4_ADDRESS_HPP

View File

@ -0,0 +1,50 @@
//
// tcp.hpp
// ~~~~~~~
//
// Copyright (c) 2003, 2004 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_IPV4_TCP_HPP
#define ASIO_IPV4_TCP_HPP
#include "asio/detail/push_options.hpp"
#include "asio/detail/socket_types.hpp"
namespace asio {
namespace ipv4 {
/// The udp class contains the flags necessary to use UDP.
class tcp
{
public:
int type() const
{
return SOCK_STREAM;
}
int protocol() const
{
return IPPROTO_TCP;
}
int family() const
{
return PF_INET;
}
};
} // namespace ipv4
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_IPV4_TCP_HPP

View File

@ -0,0 +1,50 @@
//
// udp.hpp
// ~~~~~~~
//
// Copyright (c) 2003, 2004 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_IPV4_UDP_HPP
#define ASIO_IPV4_UDP_HPP
#include "asio/detail/push_options.hpp"
#include "asio/detail/socket_types.hpp"
namespace asio {
namespace ipv4 {
/// The udp class contains the flags necessary to use UDP.
class udp
{
public:
int type() const
{
return SOCK_DGRAM;
}
int protocol() const
{
return IPPROTO_UDP;
}
int family() const
{
return PF_INET;
}
};
} // namespace ipv4
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_IPV4_UDP_HPP

View File

@ -159,6 +159,9 @@ 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;
/// Allow the socket to be bound to an address that is already in use.
typedef flag<SOL_SOCKET, SO_REUSEADDR> reuse_address;
} // namespace socket_option
} // namespace asio

View File

@ -357,7 +357,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT = ../../include ../../include/asio asio_dox.txt ../examples/tutorial/tutorial_dox.txt
INPUT = ../../include ../../include/asio ../../include/asio/ipv4 asio_dox.txt ../examples/tutorial/tutorial_dox.txt
# If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp

View File

@ -3,6 +3,11 @@
\brief The asio namespace defines all user-accessible classes and templates.
*/
/**
\namespace asio::ipv4
\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.
@ -18,6 +23,7 @@
<H2>Namespaces</H2>
\li ::asio
\li ::asio::ipv4
\li ::asio::socket_option
<H2>Core Classes</H2>
@ -32,7 +38,7 @@
<H2>Support Classes</H2>
\li asio::counting_completion_context
\li asio::inet_address_v4
\li asio::ipv4::address
\li asio::null_completion_context
\li asio::socket_error
\li asio::timer_base

View File

@ -15,7 +15,7 @@ public:
connector_(d),
socket_(d)
{
connector_.async_connect(socket_, asio::inet_address_v4(port, host),
connector_.async_connect(socket_, asio::ipv4::address(port, host),
boost::bind(&chat_client::handle_connect, this, _1));
}

View File

@ -164,7 +164,7 @@ class chat_server
public:
chat_server(asio::demuxer& d, short port)
: demuxer_(d),
acceptor_(d, asio::inet_address_v4(port))
acceptor_(d, asio::ipv4::address(port))
{
chat_session_ptr new_session(new chat_session(demuxer_, room_));
acceptor_.async_accept(new_session->socket(),

View File

@ -60,7 +60,7 @@ class server
public:
server(asio::demuxer& d, short port)
: demuxer_(d),
acceptor_(d, asio::inet_address_v4(port))
acceptor_(d, asio::ipv4::address(port))
{
session* new_session = new session(demuxer_);
acceptor_.async_accept(new_session->socket(),

View File

@ -8,7 +8,7 @@ class server
public:
server(asio::demuxer& d, short port)
: demuxer_(d),
socket_(d, asio::inet_address_v4(port))
socket_(d, asio::ipv4::address(port))
{
socket_.async_recvfrom(data_, max_length, sender_address_,
boost::bind(&server::handle_recvfrom, this, _1, _2));
@ -37,7 +37,7 @@ public:
private:
asio::demuxer& demuxer_;
asio::dgram_socket socket_;
asio::inet_address_v4 sender_address_;
asio::ipv4::address sender_address_;
enum { max_length = 1024 };
char data_[max_length];
};

View File

@ -20,7 +20,7 @@ int main(int argc, char* argv[])
using namespace std; // For atoi and strlen.
asio::stream_socket s(d);
asio::socket_connector c(d);
c.connect(s, asio::inet_address_v4(atoi(argv[2]), argv[1]));
c.connect(s, asio::ipv4::address(atoi(argv[2]), argv[1]));
std::cout << "Enter message: ";
char request[max_length];

View File

@ -31,7 +31,7 @@ void session(stream_socket_ptr sock)
void server(asio::demuxer& d, short port)
{
asio::socket_acceptor a(d, asio::inet_address_v4(port));
asio::socket_acceptor a(d, asio::ipv4::address(port));
for (;;)
{
stream_socket_ptr sock(new asio::stream_socket(d));

View File

@ -17,18 +17,18 @@ int main(int argc, char* argv[])
asio::demuxer d;
asio::dgram_socket s(d, asio::inet_address_v4(0));
asio::dgram_socket s(d, asio::ipv4::address(0));
using namespace std; // For atoi and strlen.
std::cout << "Enter message: ";
char request[max_length];
std::cin.getline(request, max_length);
size_t request_length = strlen(request);
asio::inet_address_v4 receiver_address(atoi(argv[2]), argv[1]);
asio::ipv4::address receiver_address(atoi(argv[2]), argv[1]);
s.sendto(request, request_length, receiver_address);
char reply[max_length];
asio::inet_address_v4 sender_address;
asio::ipv4::address sender_address;
size_t reply_length = s.recvfrom(reply, max_length, sender_address);
std::cout << "Reply is: ";
std::cout.write(reply, reply_length);

View File

@ -6,11 +6,11 @@ const int max_length = 1024;
void server(asio::demuxer& d, short port)
{
asio::dgram_socket sock(d, asio::inet_address_v4(port));
asio::dgram_socket sock(d, asio::ipv4::address(port));
for (;;)
{
char data[max_length];
asio::inet_address_v4 sender_address;
asio::ipv4::address sender_address;
size_t length = sock.recvfrom(data, max_length, sender_address);
sock.sendto(data, length, sender_address);
}

View File

@ -10,7 +10,7 @@ public:
accept_handler(demuxer& d)
: demuxer_(d),
timer_(d),
acceptor_(d, inet_address_v4(32123)),
acceptor_(d, ipv4::address(32123)),
socket_(d)
{
acceptor_.async_accept(socket_,

View File

@ -13,7 +13,7 @@ public:
connector_(d),
socket_(d)
{
connector_.async_connect(socket_, inet_address_v4(32123, "localhost"),
connector_.async_connect(socket_, ipv4::address(32123, "localhost"),
boost::bind(&connect_handler::handle_connect, this, _1));
timer_.set(timer::from_now, 5);
@ -49,7 +49,7 @@ int main()
try
{
demuxer d;
socket_acceptor a(d, inet_address_v4(32123), 1);
socket_acceptor a(d, ipv4::address(32123), 1);
// Make lots of connections so that at least some of them will block.
connect_handler ch1(d);

View File

@ -10,7 +10,7 @@ public:
dgram_handler(demuxer& d)
: demuxer_(d),
timer_(d),
socket_(d, inet_address_v4(32124))
socket_(d, ipv4::address(32124))
{
socket_.async_recvfrom(data_, max_length, sender_address_,
boost::bind(&dgram_handler::handle_recvfrom, this, _1, _2));
@ -40,7 +40,7 @@ private:
demuxer& demuxer_;
timer timer_;
dgram_socket socket_;
inet_address_v4 sender_address_;
ipv4::address sender_address_;
enum { max_length = 512 };
char data_[max_length];
};

View File

@ -214,7 +214,7 @@ private:
counting_completion_context context_;
timer stop_timer_;
socket_connector connector_;
inet_address_v4 server_addr_;
ipv4::address server_addr_;
size_t block_size_;
size_t max_session_count_;
std::list<session*> sessions_;

View File

@ -109,7 +109,7 @@ class server
public:
server(demuxer& d, short port, size_t block_size)
: demuxer_(d),
acceptor_(d, inet_address_v4(port)),
acceptor_(d, ipv4::address(port)),
block_size_(block_size)
{
session* new_session = new session(demuxer_, block_size_);

View File

@ -39,17 +39,19 @@ void dgram_socket_test()
demuxer d;
dgram_socket s1(d, inet_address_v4(0));
inet_address_v4 target_addr;
dgram_socket s1(d, ipv4::address(0));
ipv4::address target_addr;
s1.get_local_address(target_addr);
target_addr.host_addr_str("127.0.0.1");
dgram_socket s2(d, inet_address_v4(0));
dgram_socket s2(d);
s2.open(ipv4::udp());
s2.bind(ipv4::address(0));
char send_msg[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
s2.sendto(send_msg, sizeof(send_msg), target_addr);
char recv_msg[sizeof(send_msg)];
inet_address_v4 sender_addr;
ipv4::address sender_addr;
size_t bytes_recvd = s1.recvfrom(recv_msg, sizeof(recv_msg), sender_addr);
UNIT_TEST_CHECK(bytes_recvd == sizeof(send_msg));

View File

@ -26,45 +26,45 @@ void error_handler_test()
socket_connector c(d);
socket_error expected_err;
c.connect(s, inet_address_v4(321, "0.0.0.0"), set_error(expected_err));
c.connect(s, ipv4::address(321, "0.0.0.0"), set_error(expected_err));
std::ostringstream os;
c.connect(s, inet_address_v4(321, "0.0.0.0"), log_error(os));
c.connect(s, ipv4::address(321, "0.0.0.0"), log_error(os));
UNIT_TEST_CHECK(!os.str().empty());
os.str("");
c.connect(s, inet_address_v4(321, "0.0.0.0"),
c.connect(s, ipv4::address(321, "0.0.0.0"),
error == expected_err || log_error(os));
UNIT_TEST_CHECK(os.str().empty());
os.str("");
c.connect(s, inet_address_v4(321, "0.0.0.0"),
c.connect(s, ipv4::address(321, "0.0.0.0"),
error == expected_err && log_error(os));
UNIT_TEST_CHECK(!os.str().empty());
os.str("");
c.connect(s, inet_address_v4(321, "0.0.0.0"),
c.connect(s, ipv4::address(321, "0.0.0.0"),
error != expected_err || log_error(os));
UNIT_TEST_CHECK(!os.str().empty());
os.str("");
c.connect(s, inet_address_v4(321, "0.0.0.0"),
c.connect(s, ipv4::address(321, "0.0.0.0"),
error != expected_err && log_error(os));
UNIT_TEST_CHECK(os.str().empty());
os.str("");
c.connect(s, inet_address_v4(321, "0.0.0.0"),
c.connect(s, ipv4::address(321, "0.0.0.0"),
log_error_if(os, error == expected_err));
UNIT_TEST_CHECK(!os.str().empty());
os.str("");
c.connect(s, inet_address_v4(321, "0.0.0.0"),
c.connect(s, ipv4::address(321, "0.0.0.0"),
log_error_if(os, error != expected_err));
UNIT_TEST_CHECK(os.str().empty());
try
{
c.connect(s, inet_address_v4(321, "0.0.0.0"), throw_error());
c.connect(s, ipv4::address(321, "0.0.0.0"), throw_error());
UNIT_TEST_CHECK(0);
}
catch (socket_error&)
@ -73,7 +73,7 @@ void error_handler_test()
try
{
c.connect(s, inet_address_v4(321, "0.0.0.0"),
c.connect(s, ipv4::address(321, "0.0.0.0"),
error == expected_err || throw_error());
}
catch (socket_error&)
@ -83,7 +83,7 @@ void error_handler_test()
try
{
c.connect(s, inet_address_v4(321, "0.0.0.0"),
c.connect(s, ipv4::address(321, "0.0.0.0"),
error == expected_err && throw_error());
UNIT_TEST_CHECK(0);
}
@ -93,7 +93,7 @@ void error_handler_test()
try
{
c.connect(s, inet_address_v4(321, "0.0.0.0"),
c.connect(s, ipv4::address(321, "0.0.0.0"),
error != expected_err || throw_error());
UNIT_TEST_CHECK(0);
}
@ -103,7 +103,7 @@ void error_handler_test()
try
{
c.connect(s, inet_address_v4(321, "0.0.0.0"),
c.connect(s, ipv4::address(321, "0.0.0.0"),
error != expected_err && throw_error());
}
catch (socket_error&)
@ -113,7 +113,7 @@ void error_handler_test()
try
{
c.connect(s, inet_address_v4(321, "0.0.0.0"),
c.connect(s, ipv4::address(321, "0.0.0.0"),
throw_error_if(error == expected_err));
UNIT_TEST_CHECK(0);
}
@ -123,7 +123,7 @@ void error_handler_test()
try
{
c.connect(s, inet_address_v4(321, "0.0.0.0"),
c.connect(s, ipv4::address(321, "0.0.0.0"),
throw_error_if(error != expected_err));
}
catch (socket_error&)
@ -132,30 +132,30 @@ void error_handler_test()
}
socket_error err;
c.connect(s, inet_address_v4(321, "0.0.0.0"), set_error(err));
c.connect(s, ipv4::address(321, "0.0.0.0"), set_error(err));
UNIT_TEST_CHECK(err == expected_err);
c.connect(s, inet_address_v4(321, "0.0.0.0"),
c.connect(s, ipv4::address(321, "0.0.0.0"),
error == expected_err || set_error(err));
UNIT_TEST_CHECK(err != expected_err);
c.connect(s, inet_address_v4(321, "0.0.0.0"),
c.connect(s, ipv4::address(321, "0.0.0.0"),
error == expected_err && set_error(err));
UNIT_TEST_CHECK(err == expected_err);
c.connect(s, inet_address_v4(321, "0.0.0.0"),
c.connect(s, ipv4::address(321, "0.0.0.0"),
error != expected_err || set_error(err));
UNIT_TEST_CHECK(err == expected_err);
c.connect(s, inet_address_v4(321, "0.0.0.0"),
c.connect(s, ipv4::address(321, "0.0.0.0"),
error != expected_err && set_error(err));
UNIT_TEST_CHECK(err != expected_err);
c.connect(s, inet_address_v4(321, "0.0.0.0"),
c.connect(s, ipv4::address(321, "0.0.0.0"),
set_error_if(err, error == expected_err));
UNIT_TEST_CHECK(err == expected_err);
c.connect(s, inet_address_v4(321, "0.0.0.0"),
c.connect(s, ipv4::address(321, "0.0.0.0"),
set_error_if(err, error != expected_err));
UNIT_TEST_CHECK(err != expected_err);
}

View File

@ -33,8 +33,8 @@ void socket_acceptor_test()
{
demuxer d;
socket_acceptor acceptor(d, inet_address_v4(0));
inet_address_v4 server_addr;
socket_acceptor acceptor(d, ipv4::address(0));
ipv4::address server_addr;
acceptor.get_local_address(server_addr);
server_addr.host_addr_str("127.0.0.1");
@ -49,10 +49,10 @@ void socket_acceptor_test()
server_side_socket.close();
connector.connect(client_side_socket, server_addr);
inet_address_v4 client_addr;
ipv4::address client_addr;
acceptor.accept_address(server_side_socket, client_addr);
inet_address_v4 client_side_local_addr;
ipv4::address client_side_local_addr;
client_side_socket.get_local_address(client_side_local_addr);
UNIT_TEST_CHECK(client_side_local_addr.port() == client_addr.port());