//
// $Id: Socket.h,v 1.11 2005/07/12 19:15:37 will_mason Exp $
//
// vi: set ft=objc:

/*
 * ObjectiveLib - a library of containers and algorithms for Objective-C
 *
 * Copyright (c) 2004
 * Will Mason
 *
 * Portions:
 *
 * Copyright (c) 1994
 * Hewlett-Packard Company
 *
 * Copyright (c) 1996,1997
 * Silicon Graphics Computer Systems, Inc.
 *
 * Copyright (c) 1997
 * Moscow Center for SPARC Technology
 *
 * Copyright (c) 1999 
 * Boris Fomitchev
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * You may contact the author at will_mason@users.sourceforge.net.
 */

#if !defined(SOCKET_OL_GUARD)
#define SOCKET_OL_GUARD

/**
 * @defgroup Sockets
 *
 * A system for making use of BSD sockets. Sockets are endpoints for communication and
 * are very useful for interprocess communication and for communication between different
 * hosts. In the @b ObjectiveLib model a server socket listens for connections from
 * client sockets, and when a connection is made a new generic socket is returned
 * by the server socket through which communication can be performed using
 * @ref Streams "streams".
 */

#import <ObjectiveLib/SocketAddress.h>

@class OLInStream;
@class OLOutStream;

extern NSString* const OLSocketException;

/**
 * @class OLSocket Socket.h ObjectiveLib/Socket.h
 *
 * An abstract base class for sockets. All the common functionality that all sockets
 * possess is contained in OLSocket.
 *
 * @ingroup Sockets
 */
@interface OLSocket : NSObject
{
@protected
    /**
     * The memory allocator used by the socket
     */
    OLAllocator*        allocator;

    /**
     * The socket's in stream
     */
    OLInStream*         inStream;

    /**
     * The socket's out stream
     */
    OLOutStream*        outStream;

    /**
     * The file descriptor associated with the socket
     */
    int                 fd;
}

/**
 * @name Initializers and Deallocators
 */
/* @{ */
/**
 * Finalize the socket and deallocate any allocated memory.
 */
- (void) dealloc;
/* @} */

/**
 * Return whether this socket allows broadcasting. This message returns YES if
 * the socket is capable of sending datagrams to a broadcast address.
 *
 * @sa #setAllowsBroadcast:
 *
 * @exception OLSocketException if there is an error retrieving the information
 * @return YES if the socket allows broadcasting, NO otherwise
 */
- (BOOL) allowsBroadcast;

/**
 * Close the socket. The socket will no longer be available for communication after
 * receiving this message.

 * @exception OLSocketException if there is an error closing the socket
 */
- (void) close;

/**
 * Return whether routing is disabled. If this message returns YES, then outgoing
 * messages will bypass standard routing facilities.
 *
 * @sa #setDontRoute:
 *
 * @exception OLSocketException if there is an error retrieving the information
 * @return YES if routing is disabled, NO otherwise
 */
- (BOOL) dontRoute;

/**
 * Return whether the platform supports reusing ports. This information can also be
 * gleaned at compile time by checking whether OL_HAVE_SO_REUSEPORT is defined. If
 * this message returns YES, then the messages #reusePort and #setReusePort: can
 * meaningfully be used.
 *
 * If this messages returns YES then more than one socket can be bound to the same
 * port and all broadcast datagrams will be received by all sockets sharing the port.
 *
 * @sa #reusePort, #setReusePort:
 *
 * @return YES if the platform support reusing ports, NO otherwise
 */
- (BOOL) hasReusePortSupport;

/**
 * Return the in stream associated with the socket. The in stream can be used to read
 * data written by the socket connected to this one. The in stream returned is
 * guaranteed to live as long as the socket does. If you attempt to retain and use
 * the in stream after releasing the socket, you'll discover that it doesn't work.
 *
 * @sa #outStream
 *
 * @return the socket's in stream
 */
- (OLInStream*) inStream;

/**
 * Return whether "keep alive" is enabled. If this message returns YES, then the socket
 * will periodically send messages to its peer in order to make sure the connection
 * remains active.
 *
 * @sa #setKeepAlive:
 *
 * @exception OLSocketException if there is an error retrieving the information
 * @return YES if "keep alive" is enabled, NO otherwise
 */
- (BOOL) keepAlive;

/**
 * Return the number of seconds to linger. If a linger interval is set, then the
 * socket will block when #close is called for the given number seconds while there
 * is data remaining for the socket to transmit. If no linger interval is set,
 * then this message return UINT_MAX. Also, if linger is set to zero, then
 * #close will not block, and pending data will be discarded. If linger is not
 * enabled, then #close will not block, but pending data will be sent anyway.
 *
 * @sa #setLinger:
 *
 * @exception OLSocketException if there is an error retrieving the information
 * @return the number of seconds to linger or UINT_MAX if linger is not enabled
 */
- (unsigned) linger;

/**
 * Return the local address. The local address is the address to which this socket
 * is bound.
 *
 * @sa #remoteAddress
 *
 * @exception OLSocketException if the socket is not bound to a local address
 * @return the local address
 */
- (OLSocketAddress*) localAddress;

/**
 * Return whether out-of-band data is received inline. When this message returns YES
 * then all out-of-band data received on the socket will be mixed in with the
 * normal data transmitted to the socket by its peer.
 *
 * @sa #setOutOfBandInline:
 *
 * @exception OLSocketException if there is an error retrieving the information
 * @return YES if out-of-band data is received inline, NO otherwise
 */
- (BOOL) outOfBandInline;

/**
 * Return the out stream associated with the socket. The out stream can be used to write
 * data that can be read by the socket's peer. The out stream returned is
 * guaranteed to live as long as the socket does. If you attempt to retain and use
 * the stream after releasing the socket, you'll discover that it doesn't work.
 *
 * @sa #inStream
 *
 * @return the socket's out stream
 */
- (OLOutStream*) outStream;

/**
 * Return the size of the buffer for received data. The system maintains a buffer for
 * receiving data. This message tells you its size.
 *
 * @sa #setReceiveBufferSize:
 *
 * @exception OLSocketException if there is an error retrieving the information
 * @return the size of the buffer for received data
 */
- (unsigned) receiveBufferSize;

/**
 * Return the low-water mark for receiving data. The low-water mark refers to the
 * minimum number of bytes for input operations.
 *
 * @sa #setReceiveLowWaterMark:
 *
 * @exception OLSocketException if there is an error retrieving the information
 * @return the minimum number of bytes for input
 */
- (unsigned) receiveLowWaterMark;

/**
 * Return the time out for receiving data. This value is the maximum amount of time
 * in milliseconds that the socket will wait to receive requested data.
 *
 * @sa #setReceiveTimeOut:
 *
 * @exception OLSocketException if there is an error retrieving the information
 * @return the number of milliseconds to wait to receive data
 */
- (unsigned) receiveTimeOut;

/**
 * Return the address of the socket's peer. The remote address is the one to which
 * this socket is connected.
 *
 * @sa #localAddress
 *
 * @exception OLSocketException if there is a problem retrieving the address
 * @return the remote address
 */
- (OLSocketAddress*) remoteAddress;

/**
 * Return whether reusing of addresses is enabled. If this message returns YES, then
 * this socket may be bound to an address that is in a time out state.
 *
 * @sa #setReuseAddress:
 *
 * @exception OLSocketException if there is an error retrieving the information
 * @return YES if this socket can reuse an address, NO otherwise
 */
- (BOOL) reuseAddress;

/**
 * Return whether this socket can reuse a port. If this message returns YES, then this
 * socket can be bound to a port already in use by another socket for the purposes of
 * receiving broadcast datagrams.
 *
 * @note If the message #hasReusePortSupport returns NO, then this message always
 * returns NO.
 *
 * @sa #setReusePort:, #hasReusePortSupport
 *
 * @exception OLSocketException if there is an error retrieving the information
 * @return YES if this socket can reuse ports, NO otherwise
 */
- (BOOL) reusePort;

/**
 * Return the size of the buffer for sent data. The system maintains a buffer for
 * sending data. This message tells you its size.
 *
 * @sa #setSendBufferSize:
 *
 * @exception OLSocketException if there is an error retrieving the information
 * @return the size of the buffer for sent data
 */
- (unsigned) sendBufferSize;

/**
 * Return the low-water mark for sending data. The low-water mark refers to the
 * minimum number of bytes for output operations.
 *
 * @sa #setSendLowWaterMark:
 *
 * @exception OLSocketException if there is an error retrieving the information
 * @return the minimum number of bytes for output
 */
- (unsigned) sendLowWaterMark;

/**
 * Return the time out for sending data. This value is the maximum amount of time
 * in milliseconds that the socket will wait to send data.
 *
 * @sa #setSendTimeOut:
 *
 * @exception OLSocketException if there is an error retrieving the information
 * @return the number of milliseconds to wait to send data
 */
- (unsigned) sendTimeOut;

/**
 * Set whether this socket allows broadcasting. Set @a state to YES if
 * the socket should be capable of sending datagrams to a broadcast address.
 *
 * @sa #allowsBroadcast
 *
 * @exception OLSocketException if there is an error setting the information
 * @param state YES if the socket should allow broadcast, NO if not
 */
- (void) setAllowsBroadcast: (BOOL)state;

/**
 * Set whether routing is disabled. Set @a state to YES if outgoing
 * messages should bypass standard routing facilities.
 *
 * @sa #dontRoute
 *
 * @exception OLSocketException if there is an error setting the information
 * @param state YES if routing should be disabled, NO if not
 */
- (void) setDontRoute: (BOOL)state;

/**
 * Set whether "keep alive" is enabled. Set @a state to YES if the socket
 * should periodically send messages to its peer in order to make sure the connection
 * remains active.
 *
 * @sa #keepAlive
 *
 * @exception OLSocketException if there is an error setting the information
 * @param state YES if keep alive should be enabled, NO if not
 */
- (void) setKeepAlive: (BOOL)state;

/**
 * Set the number of seconds to linger. If a linger interval is set, then the
 * socket will block when #close is called for the given number seconds while there
 * is data remaining for the socket to transmit. If linger is set to zero, then
 * #close will not block, and pending data will be discarded. If linger is not
 * enabled, then #close will not block, but pending data will be sent anyway.
 *
 * To disable lingering @a value should be set to UINT_MAX.
 *
 * @sa #linger
 *
 * @exception OLSocketException if there is an error setting the information
 * @param value the number of seconds to linger or UINT_MAX if lingering should be
 * disabled
 */
- (void) setLinger: (unsigned)value;

/**
 * Set whether out-of-band data is received inline. Set @a state to YES to
 * make all out-of-band data received on the socket to be mixed in with the
 * normal data transmitted to the socket by its peer.
 *
 * @sa #outOfBandInline
 *
 * @exception OLSocketException if there is an error setting the information
 * @param state YES if out-of-band data should be received inline, NO if not
 */
- (void) setOutOfBandInline: (BOOL)state;

/**
 * Set the size of the buffer for receiving data.
 *
 * @sa #receiveBufferSize
 *
 * @exception OLSocketException if there is an error setting the information
 * @param size the new size of the receive buffer
 */
- (void) setReceiveBufferSize: (unsigned)size;

/**
 * Set the low-water mark for receiving data. The low-water mark refers to the
 * minimum number of bytes for input operations.
 *
 * @sa #receiveLowWaterMark
 *
 * @exception OLSocketException if there is an error setting the information
 * @param value the minimum number of bytes for input
 */
- (void) setReceiveLowWaterMark: (unsigned)value;

/**
 * Set the time out for receiving data. This value is the maximum amount of time
 * in milliseconds that the socket will wait to receive requested data.
 *
 * @sa #receiveTimeOut
 *
 * @exception OLSocketException if there is an error setting the information
 * @param value the number of milliseconds to wait to receive data
 */
- (void) setReceiveTimeOut: (unsigned)value;

/**
 * Set whether reusing of addresses is enabled. Set @a state to YES to enable
 * this socket to be bound to an address that is in a time out state.
 *
 * @sa #reuseAddress
 *
 * @exception OLSocketException if there is an error setting the information
 * @param state YES if this socket should be able to reuse an address, NO if not
 */
- (void) setReuseAddress: (BOOL)state;

/**
 * Set whether this socket can reuse a port. Set @a state to YES so that this
 * socket can be bound to a port already in use by another socket for the purposes of
 * receiving broadcast datagrams.
 *
 * @note If the message #hasReusePortSupport returns NO, then this message has no
 * effect.
 *
 * @sa #reusePort, #hasReusePortSupport
 *
 * @exception OLSocketException if there is an error setting the information
 * @param state YES if this socket should be able to reuse ports, NO if not
 */
- (void) setReusePort: (BOOL)state;

/**
 * Set the size of the buffer for sending data.
 *
 * @sa #sendBufferSize
 *
 * @exception OLSocketException if there is an error setting the information
 * @param size the new size of the send buffer
 */
- (void) setSendBufferSize: (unsigned)size;

/**
 * Set the low-water mark for sending data. The low-water mark refers to the
 * minimum number of bytes for output operations.
 *
 * @sa #sendLowWaterMark
 *
 * @exception OLSocketException if there is an error setting the information
 * @param value the minimum number of bytes for output
 */
- (void) setSendLowWaterMark: (unsigned)value;

/**
 * Set the time out for sending data. This value is the maximum amount of time
 * in milliseconds that the socket will wait to send data.
 *
 * @sa #sendTimeOut
 *
 * @exception OLSocketException if there is an error setting the information
 * @param value the number of milliseconds to wait to send data
 */
- (void) setSendTimeOut: (unsigned)value;

/**
 * Disallow incoming data to be received. After sending this message it will be
 * impossible to read any more data from the socket.
 *
 * @exception OLSocketException if there was a problem shutting down the socket
 */
- (void) shutdownRead;

/**
 * Disallow outgoing data to be sent. After sending this message it will be
 * impossible to send any more data to the socket.
 *
 * @exception OLSocketException if there was a problem shutting down the socket
 */
- (void) shutdownWrite;

/**
 * Return the type of socket. The value returned is a platform-dependent number that
 * represents the type of the socket. This number will correspond to a defined
 * value such as SOCK_STREAM or SOCK_DGRAM.
 *
 * @exception OLSocketException if there was a problem retrieving the information
 * @return the type of the socket
 */
- (int) socketType;

@end

/**
 * @class OLBindableSocket Socket.h ObjectiveLib/Socket.h
 *
 * A socket that can be bound to a local address.
 *
 * @ingroup Sockets
 */
@interface OLBindableSocket : OLSocket
{
}

/**
 * Bind the socket to a local address. After successfully sending this message the
 * socket will be assigned the local @a address.
 *
 * @exception OLSocketException if there is a problem binding the socket
 * @param address the address that should be assigned to the socket
 */
- (void) bindToAddress: (OLSocketAddress*)address;

@end

/**
 * @class OLServerSocket Socket.h ObjectiveLib/Socket.h
 *
 * A socket that can accept connections from clients. A server socket typically binds
 * itself to a local address, and then waits for connections to come in via
 * #acceptConnection. When a connection is received a new socket is returned that can
 * be used to communicate with the client, while the server typically returns to
 * waiting for connections by calling #acceptConnection again. This model of usage
 * usually occurs in a multithreaded or multiprocess environment.
 *
 * @sa OLClientSocket
 *
 * @ingroup Sockets
 */
@interface OLServerSocket : OLBindableSocket
{
@protected
    /**
     * The number of clients that can be made to wait at any given time
     */
    unsigned queueLength;
}

/**
 * @name Initializers and Deallocators
 */
/* @{ */
/**
 * Initialize the socket. The socket remains unbound to a local address, has a queue length
 * of 50 and uses the default memory allocator.
 *
 * @exception OLSocketException if the socket cannot be initialized
 * @return a reference to this socket
 */
- (id) init;

/**
 * Initialize the socket. The socket is bound to @a address, has a queue length of 50 and
 * uses the default memory allocator.
 *
 * @exception OLSocketException if the socket cannot be initialized
 * @param address the local address to which this socket should be bound
 * @return a reference to this socket
 */
- (id) initWithLocalAddress: (OLSocketAddress*)address;

/**
 * Initialize the socket. The socket is bound to @a address, has a queue length of
 * @a qLen and uses the default memory allocator.
 *
 * @exception OLSocketException if the socket cannot be initialized
 * @param address the local address to which this socket should be bound
 * @param qLen the length of the server's queue
 * @return a reference to this socket
 */
- (id) initWithLocalAddress: (OLSocketAddress*)address queueLength: (unsigned)qLen;

/**
 * Initialize the socket. The socket is bound to @a address, has a queue length of
 * @a qLen and uses the given memory allocator.
 *
 * @exception OLSocketException if the socket cannot be initialized
 * @param address the local address to which this socket should be bound
 * @param qLen the length of the server's queue
 * @param alloc the memory allocator that should be used
 * @return a reference to this socket
 */
- (id) initWithLocalAddress: (OLSocketAddress*)address queueLength: (unsigned)qLen allocator: (OLAllocator*)alloc;

/**
 * Initialize the socket. The socket remains unbound to a local address, has a queue length
 * of @a qLen and uses the default memory allocator.
 *
 * @exception OLSocketException if the socket cannot be initialized
 * @param qLen the length of the server's queue
 * @return a reference to this socket
 */
- (id) initWithQueueLength: (unsigned)qLen;

/**
 * Initialize the socket. The socket remains unbound to a local address, has a queue length
 * of @a qLen and uses the given memory allocator.
 *
 * @exception OLSocketException if the socket cannot be initialized
 * @param qLen the length of the server's queue
 * @param alloc the memory allocator that should be used
 * @return a reference to this socket
 */
- (id) initWithQueueLength: (unsigned)qLen allocator: (OLAllocator*)alloc;
/* @} */

/**
 * Accept a connection. This method will block until a connection is received. The returned
 * socket can be used to communicate with the client that has initiated the connection.
 *
 * @exception OLSocketException if there is a problem attempting to accept a connection
 * @return a new socket that is connected to the client that initiated the connection
 */
- (OLSocket*) acceptConnection;
- (void) bindToAddress: (OLSocketAddress*)address;

/**
 * Return the queue length. The queue length represents the number of clients that
 * can wait at any given time for a server to accept a connection to them.
 *
 * @return the queue length
 */
- (unsigned) queueLength;

@end

/**
 * @class OLClientSocket Socket.h ObjectiveLib/Socket.h
 *
 * A socket that can initiate a connection with a server. A client typically obtains
 * the address of a server and connects to it by calling #connectToAddress:.
 * After a successful connection is made the client may use its streams to communicate
 * with the server.
 *
 * A client may bind to a local address, but it is not strictly necessary. A local
 * address will be automatically assigned to the client when a connection is made
 * if the client does not already have a local address.
 *
 * @sa OLServerSocket
 *
 * @ingroup Sockets
 */
@interface OLClientSocket : OLBindableSocket
{
}

/**
 * @name Initializers and Deallocators
 */
/* @{ */
/**
 * Initialize the socket. The socket uses the default memory allocator.
 *
 * @exception OLSocketException if the socket cannot be initialized
 * @return a reference to this socket
 */
- (id) init;

/**
 * Initialize the socket. The socket uses the given memory allocator.
 *
 * @exception OLSocketException if the socket cannot be initialized
 * @param alloc the memory allocator to use
 * @return a reference to this socket
 */
- (id) initWithAllocator: (OLAllocator*)alloc;

/**
 * Initialize the socket. The socket is immediately connected to the address
 * @a remote and uses the default memory allocator.
 *
 * @exception OLSocketException if the socket cannot be initialized
 * @param remote the server to which this client should connect
 * @return a reference to this socket
 */
- (id) initWithRemoteAddress: (OLSocketAddress*)remote;

/**
 * Initialize the socket. The socket is immediately connected to the address
 * @a remote and uses the given memory allocator.
 *
 * @exception OLSocketException if the socket cannot be initialized
 * @param remote the server to which this client should connect
 * @param alloc the memory allocator to use
 * @return a reference to this socket
 */
- (id) initWithRemoteAddress: (OLSocketAddress*)remote allocator: (OLAllocator*)alloc;

/**
 * Initialize the socket. The socket is immediately bound to the address @a local,
 * connected to the address @a remote and uses the default memory allocator.
 *
 * @exception OLSocketException if the socket cannot be initialized
 * @param remote the server to which this client should connect
 * @param local the address to which this socket should be bound
 * @return a reference to this socket
 */
- (id) initWithRemoteAddress: (OLSocketAddress*)remote localAddress: (OLSocketAddress*)local;

/**
 * Initialize the socket. The socket is immediately bound to the address @a local,
 * connected to the address @a remote and uses the given memory allocator.
 *
 * @exception OLSocketException if the socket cannot be initialized
 * @param remote the server to which this client should connect
 * @param local the address to which this socket should be bound
 * @param alloc the memory allocator to use
 * @return a reference to this socket
 */
- (id) initWithRemoteAddress: (OLSocketAddress*)remote localAddress: (OLSocketAddress*)local allocator: (OLAllocator*)alloc;
/* @} */

/**
 * Connect to a server. The server at @a address is contacted to establish a connection.
 *
 * @exception OLSocketException if the connection cannot be made
 * @param address the address of the server to which to connect
 */
- (void) connectToAddress: (OLSocketAddress*)address;

@end

/**
 * @class OLInternetServerSocket Socket.h ObjectiveLib/Socket.h
 *
 * A server socket that communicates via the Internet. This is a specialized
 * server that operates within the Internet address family. It is capable
 * of accepting connections from any Internet address family socket,
 * including OLInternetClientSocket.
 *
 * @sa OLInternetClientSocket, OLInternetAddress
 *
 * @ingroup Sockets
 */
@interface OLInternetServerSocket : OLServerSocket
{
}

/**
 * Create and return a new socket. An unbound server socket is created that has a
 * queue length of 50 and uses the default memory allocator.
 *
 * @exception OLSocketException if the socket cannot be created
 * @return a reference to the newly created socket
 */
+ (id) socket;

/**
 * Create and return a new socket. A server socket is created that is bound
 * to the local @a address, has a queue length of 50 and uses the default memory allocator.
 *
 * @exception OLSocketException if the socket cannot be created and bound
 * @param address the address to which the socket should be bound
 * @return a reference to the newly created socket
 */
+ (id) socketWithLocalInternetAddress: (OLInternetAddress*)address;

/**
 * Create and return a new socket. A server socket is created that is bound
 * to the local @a address, has a queue length of @a qLen and uses the default
 * memory allocator.
 *
 * @exception OLSocketException if the socket cannot be created and bound
 * @param address the address to which the socket should be bound
 * @param qLen the length of the server's queue
 * @return a reference to the newly created socket
 */
+ (id) socketWithLocalInternetAddress: (OLInternetAddress*)address queueLength: (unsigned)qLen;

/**
 * Create and return a new socket. An unbound server socket is created that has a
 * queue length of @a qLen and uses the default memory allocator.
 *
 * @exception OLSocketException if the socket cannot be created
 * @param qLen the length of the server's queue
 * @return a reference to the newly created socket
 */
+ (id) socketWithQueueLength: (unsigned)qLen;

@end

/**
 * @class OLInternetClientSocket Socket.h ObjectiveLib/Socket.h
 *
 * A client socket that communicates via the Internet. This is a specialized
 * client that operates within the Internet address family. It is capable
 * of connecting to any Internet address family socket,
 * including OLInternetServerSocket.
 *
 * @sa OLInternetServerSocket, OLInternetAddress
 *
 * @ingroup Sockets
 */
@interface OLInternetClientSocket : OLClientSocket
{
}

/**
 * Create and return a new socket. The unconnected socket uses the default
 * memory allocator.
 *
 * @exception OLSocketException if the socket cannot be created
 * @return a reference to the newly created socket
 */
+ (id) socket;

/**
 * Create and return a new socket. The socket is immediately connected to the
 * address @a remote and uses the default memory allocator.
 *
 * @exception OLSocketException if the socket cannot be created and connected
 * @param remote the remote address to which to connect
 * @return a reference to the newly created socket
 */
+ (id) socketWithRemoteInternetAddress: (OLInternetAddress*)remote;

/**
 * Create and return a new socket. The socket is immediately bound to the address
 * @a local, connected to the address @a remote and uses the default memory allocator.
 *
 * @exception OLSocketException if the socket cannot be created and connected
 * @param remote the remote address to which to connect
 * @param local the local address to which to bind
 * @return a reference to the newly created socket
 */
+ (id) socketWithRemoteInternetAddress: (OLInternetAddress*)remote localAddress: (OLInternetAddress*)local;

@end

#if defined(OL_HAVE_UNIX_SOCKETS)

/**
 * A server socket that communciates in the Unix domain. Unix domain sockets don't
 * necessarily have anything to do with Unix; it's just a description of the
 * address family. This class is capable of accepting connections from any
 * Unix domain socket, include OLUnixClientSocket.
 *
 * @sa OLUnixClientSocket, OLUnixAddress
 *
 * @ingroup Sockets
 */
@interface OLUnixServerSocket : OLServerSocket
{
@protected
    /**
     * The local address to which this server is bound
     */
    OLUnixAddress* localAddress;
}

/**
 * Create and return a new socket.
 * @copydoc OLInternetServerSocket::socket
 */
+ (id) socket;

/**
 * Create and return a new socket.
 * @copydoc OLInternetServerSocket::socketWithLocalInternetAddress:
 */
+ (id) socketWithLocalUnixAddress: (OLUnixAddress*)address;

/**
 * Create and return a new socket.
 * @copydoc OLInternetServerSocket::socketWithLocalInternetAddress:queueLength:
 */
+ (id) socketWithLocalUnixAddress: (OLUnixAddress*)address queueLength: (unsigned)qLen;

/**
 * Create and return a new socket.
 * @copydoc OLInternetServerSocket::socketWithQueueLength:
 */
+ (id) socketWithQueueLength: (unsigned)qLen;

- (void) bindToAddress: (OLSocketAddress*)address;
- (void) close;
- (OLSocketAddress*) localAddress;

@end

/**
 * @class OLUnixClientSocket Socket.h ObjectiveLib/Socket.h
 *
  * A client socket that communciates in the Unix domain. Unix domain sockets don't
 * necessarily have anything to do with Unix; it's just a description of the
 * address family. This class is capable of connecting to Unix domain socket,
 * including OLUnixServerSocket.
 *
 * @sa OLUnixServerSocket, OLUnixAddress
 *
 * @ingroup Sockets
 */
@interface OLUnixClientSocket : OLClientSocket
{
}

/**
 * Create and return a new socket.
 * @copydoc OLInternetClientSocket::socket
 */
+ (id) socket;

/**
 * Create and return a new socket.
 * @copydoc OLInternetClientSocket::socketWithRemoteInternetAddress:
 */
+ (id) socketWithRemoteUnixAddress: (OLUnixAddress*)remote;

/**
 * Create and return a new socket.
 * @copydoc OLInternetClientSocket::socketWithRemoteInternetAddress:localAddress:
 */
+ (id) socketWithRemoteUnixAddress: (OLUnixAddress*)remote localAddress: (OLUnixAddress*)local;

- (void) bindToAddress: (OLSocketAddress*)address;

@end

#endif

#endif
