[Home]BoostSocket/DataSocketConcept

BOOST WIKI | BoostSocket | RecentChanges | Preferences | Page List | Links List

Difference (from prior major revision) (no other diffs)

Changed: 1,184c1,99

Data Socket Concept




A data socket is created by an acceptor sockect or by a connector

* data_socket(const data_socket& s)
* data_socket(const socket_base& s)
* data_socket(socket_type socket)

* template <typename SocketOption?> int ioctl(SocketOption?& option)
* template <typename SocketOption?> int getsockopt(SocketOption?& option)
* template <typename SocketOption?> int setsockopt(const SocketOption?& option)

* int recv(void* data, int len)
* int send(const void* data, int len)

* SocketError? shutdown(Direction how=Both)
* SocketError? close()
* bool is_valid() const

* socket_type socket()
* socket_base& base()
* bool operator<(const data_socket& socket) const
* bool operator==(const data_socket& socket) const
* bool operator!=(const data_socket& socket) const

An interface like the one below has some advantages:
* supports both blocking an non blocking operations without having to resort to setting and not setting blocking mode this can be handled by this class (this is error prone from a user perspective)
* supports receive_full another novice misstake not taking into account that sockets are streaming, receive_full would call receive until byteCount bytes is received.
* reports a pair of result and size avoiding another common mistake not checking for disconnection
* protocol is supplied as a policy and can be supplied with user. ie one could supply my_socket_impl supporting the socket base interface with added functionality or redesigned or maybe using proprietary X25 lib or something like that.
* more readable names receive not recv more suitable for easy to use level2 functionality. use socket_base for hardcore "socket" api near programming.

template<typename PROTOCOL, typename ADDRESS = PROTOCOL::address_type_tl::head>
struct data_connection
{
typedef PROTOCOL protocol_t;
typedef ADDRESS address_t;
typedef boost::posix_time::time_duration duration_t;

struct result
{
enum enum_t
{
success,
partial,
disconnected,
would_block,
.... other common errcodes
specific_error
}
};

data_connection(protocol_t protocol = protocol_t());

/// blocking
std::pair<result::enum_t,unsigned> send(void*, unsigned int);
std::pair<result::enum_t,unsigned> receive(void* data, unsigned int byteCount);
std::pair<result::enum_t,unsigned> receive_full(void*, unsigned int byteCount);

/// non blocking
std::pair<result::enum_t,unsigned> send(void*, unsigned int, duration_t timeoutSecs);
std::pair<result::enum_t,unsigned> receive(void* data, unsigned int byteCount, duration_t timeoutSecs);
std::pair<result::enum_t,unsigned> receive_full(void*, unsigned int byteCount, duration_t timeoutSecs);

const address_t& local_address() const;
const address_t& remote_address() const;

void close();

result::enum_t shutdown(Direction how=Both)
bool is_valid() const

bool operator<(const data_connection& socket) const;
bool operator==(const data_connection& socket) const;
bool operator!=(const data_connection& socket) const;

protocol_t& protocol() const; // access underlying protocol


unsigned last_specific_error();
private:
data_connection(const data_connection<PROTOCOL, ADDRESS>&);
data_connection<PROTOCOL, ADDRESS>& operator=(const data_connection<PROTOCOL, ADDRESS>&);

protocol_t m_protocol;
};

PROTOCOL would be an protocol policy class like:
struct tcp : public socket_base
{
defines and things describing what options and what type of protocol tcp is
these should be used as conceptual checks if protocol can be used with certain address types
and connectors and acceptors.

typedef TYPELIST<ip_end_point> address_type_tl;
typedef TYPELIST<....> supported_options_tl;
};

This is rather sketchy but can be worked out more closely if the ideas are liked.

Data Socket Concept

A data socket is created by an acceptor sockect or by a connector

An interface like the one below has some advantages:

    template<typename PROTOCOL, typename ADDRESS = PROTOCOL::address_type_tl::head>
    struct data_connection
    {
        typedef PROTOCOL protocol_t;
        typedef ADDRESS address_t;
        typedef boost::posix_time::time_duration duration_t;

        struct result
        {
            enum enum_t
            {
                success,
                partial,
                disconnected,
                would_block,
                .... other common errcodes
                specific_error
            }
        };

        data_connection(protocol_t protocol = protocol_t());

        /// blocking
        std::pair<result::enum_t,unsigned> send(void*, unsigned int);
        std::pair<result::enum_t,unsigned> receive(void* data, unsigned int byteCount);
        std::pair<result::enum_t,unsigned> receive_full(void*, unsigned int byteCount);

        /// non blocking
        std::pair<result::enum_t,unsigned> send(void*, unsigned int, duration_t timeoutSecs);
        std::pair<result::enum_t,unsigned> receive(void* data, unsigned int byteCount, duration_t timeoutSecs);
        std::pair<result::enum_t,unsigned> receive_full(void*, unsigned int byteCount, duration_t timeoutSecs);

        const address_t& local_address() const;
        const address_t& remote_address() const;

        void close();

        result::enum_t shutdown(Direction how=Both)
        bool is_valid() const

        bool operator<(const data_connection& socket) const;
        bool operator==(const data_connection& socket) const;
        bool operator!=(const data_connection& socket) const;

        protocol_t& protocol() const; // access underlying protocol

        unsigned last_specific_error();
    private:
        data_connection(const data_connection<PROTOCOL, ADDRESS>&);
        data_connection<PROTOCOL, ADDRESS>& operator=(const data_connection<PROTOCOL, ADDRESS>&);

        protocol_t           m_protocol;
    };

PROTOCOL would be an protocol policy class like:

   struct tcp : public socket_base
   {
   defines and things describing what options and what type of protocol tcp is
   these should be used as conceptual checks if protocol can be used with certain address types 
   and connectors and acceptors.

   typedef TYPELIST<ip_end_point> address_type_tl; 
   typedef TYPELIST<....> supported_options_tl;
   };

This is rather sketchy but can be worked out more closely if the ideas are liked.


BOOST WIKI | BoostSocket | RecentChanges | Preferences | Page List | Links List
Edit text of this page | View other revisions
Last edited December 18, 2004 12:30 pm (diff)
Search:
Disclaimer: This site not officially maintained by Boost Developers