Boost logo

Boost :

From: Hamish Mackenzie (hamish_at_[hidden])
Date: 2002-11-24 15:49:06


http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?BoostSocket/SocketErrorConcept

send and recv cannot return 0 for Success as they must return a count of
bytes read or written.

Can we have three types of non-exception return value

success > 0
want_read = -???
want_write = -???

I use this in my wrappers for openssl. A write on an ssl stream can
block attempting to read from the underlying socket (and vice-versa).

With two different "would block" return values we can have functions
like...

template< typename SocketType >
inline int send(
        SockectType & s,
        void * data,
        int len,
        SocketSet & read_set,
        SocketSet & write_set )
{
        int result = s.send( data, len );
        if( result == want_read )
        {
                read_set.insert( s );
        }
        else if( result == want_write )
        {
                write_set.insert( s );
        }
        return result;
}

Another tricky issue with openssl is the ability to have different read
and write file descriptors for an ssl connection. In my code I have a
file_descriptor_set instead of a socket_set. This means I can use..
        read_set.insert( s.read_fd() );
and
        read_set.insert( s.write_fd() );

Could we add members read_socket and write_socket, that would return
*this for most sockets?

In my opinion socket_exception should derive from std::exception.
However what() should return nothing more than "socket error". The
reason for this is that any more information like "dns lookup error for
host xyz.abc.com" could reveal sensitive information about ones network.

I like the idea of having an error policy

namespace socket_function
{
enum { connect, send, recv, ... };
}

struct default_error_policy
{
        template< typename TupleArgs >
        int handle_error( int err, sockect_function f, TupleArgs args )
        {
                throw socket_exception();
        }

        BOOST_STATIC_CONSTANT( bool, nothrow = false );
}

struct nothrow_error_policy
{
        template< typename TupleArgs >
        int handle_error( int err, sockect_function f, TupleArgs args )
        {
                return err;
        }

        BOOST_STATIC_CONSTANT( bool, nothrow = true );
}

template< typename ErrorPolicy >
class basic_socket
{
public:
        typedef ErrorPolicy error_policy;
...
};

typedef basic_socket< default_error_policy > socket;

The args tuple would include the socket itself followed by the args.

Implementors of handle_error would have two options
1) return err;
2) throw a type derived from socket_exception;

They could log errors or provide more detail in the socket_error derived
exception.

-- 
Hamish Mackenzie <hamish_at_[hidden]>

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk