Boost logo

Boost :

From: Hugo Duncan (hugoduncan_at_[hidden])
Date: 2003-11-07 16:27:14


Hi,

Since discussions on sockets has restarted, I have tried to pull together
what I have put together following discussions around this time last year,
and have uploaded it to:

http://groups.yahoo.com/group/boost/files/NetworkLib/net031107.tar.gz

This doesn't have a socket stream and doesn't have an error policy that
throws exceptions, so hopefully it is complementary to the work posted
by Jessie Hernandez.

What is there:

    Level 0
      Low level wrapper for socket, named_pipe
      Low level wrapper select, and completion ports.
       - avoid platform includes, platform independent error codes,
          no state management

    Level 1
      Connector, Acceptor and Connection pattern classes for sockets and
      named pipes.
       - policy based handling of the ipc (socket/named_pipe) error codes
       - conversion to ipc (socket/named_pipe)independent, logical error
codes

      Proactor implementation using completion ports
      Reactor implementation using select

    Level 2
      Connector, Acceptor and Connection pattern classes to connect user
      handlers
        - user connection handlers must either
          x implement a concept (no virtual functions, no boost functions)
          x implement a virtual interface (polymorphic run time handlers)
          x implement a concept (boost functions - handler type changeable
at run time)

        - policy based handling of the logical
(connection/acceptor/connector)
          error_codes
        - connection closure policies (handler notification and self
deletion
          are the two implemented policies)

      Implementation independent wrapper for Reactor and Proactor

      The Connector, Acceptor and Connection classes are useable with either
      reactor or proactor with no change to the user handler classes.

      Acceptor, connector type generators that allow switching between
sockets
      and named_pipes with a single typedef.

This is "proof of concept" code, and works (with compiler warnings) on
VC++ 7.1

Examples included are an echo server (included below), and a "ping pong"
server
and client.

The ping pong server accepts both socket and named pipe connections, and
maintains
a list of connections.

The client connects on both a socket and on a named pipe. Connections are
auto deleted.

I will be offline until Monday.

Hugo

//// Echo server

namespace socket = boost::net::socket ;
namespace net = boost::net ;

class echo_server;
class echo_acceptor;

namespace
{
   const int buf_size(1024);
}

class echo_connection;

//! select which demultiplexer to use
// typedef net::proactor<> demultiplexer_t;
typedef net::reactor<> demultiplexer_t;

typedef socket::connection<
   demultiplexer_t,
   demultiplexer_t::synchronisation_type,
   socket::default_error_policy,
   net::connection_handler_typed<echo_connection>
> socket_connection_t;

typedef socket::acceptor<
   demultiplexer_t
   , demultiplexer_t::synchronisation_type
   , socket_connection_t
> socket_acceptor_peer;

typedef net::acceptor<
   socket_acceptor_peer,
   echo_server
> socket_acceptor_t;

//! Echo connection class
class echo_connection
{
public:
   typedef net::connection<socket_connection_t> connection_t;
   typedef socket_connection_t connection_peer;

   //! Constructor from underlying connection peer object
   echo_connection(connection_peer* connection) : data(connection, this) {}
   ~echo_connection(){}

   void on_open() { data.read(read_buf,buf_size); }
   void on_read(std::size_t n) { data.write(read_buf,n);}
   void on_written(std::size_t n) { data.read(read_buf,buf_size); }
   void on_close(){}

private:
   connection_t data;
   // buffer used for reading
   char read_buf[buf_size];
};

class echo_server
{
public:

   echo_server() : m_socket_acceptor(*this, demultiplexer) {}

   //! Handler for when a connection has been accepted
   echo_connection* accept(socket_connection_t* connection,
                           const socket::any_address& address)
   {
     return new echo_connection(connection);
   }

   void run()
   {
     // open server endpoint
     m_socket_acceptor.open(
       socket::make_endpoint(
         socket::ip4::tcp_protocol(),
         socket::ip4::address("127.0.0.1",7)) );

     // start an accept to get things running
     m_socket_acceptor.activate();

     demultiplexer.run();
   }

private:
   demultiplexer_t demultiplexer;
   socket_acceptor_t m_socket_acceptor;
};

int main(int, char**)
{
   echo_server server;
   server.run();
}


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