Author: James CE Johnson

ACE Tutorial 015
Building a protocol stream

Like the client, we want to keep the main() part of our server code as simple as possible. This is done by putting most of the work into the Handler object that will deal with client connections. From the looks of the code below, I think we've been successful in our simplification.

    // page05.html,v 1.13 1999/04/03 21:56:29 jcej Exp

    #include "Server_i.h"
    #include "ace/Select_Reactor.h"

    // A signal handler that will close the server object
    extern "C" void handler (int)
    {
        Server::close();
    }

    int main (int, char **)
    {
            /* On Win32, the WFMO reactor is used by default.
               Unfortunately, that causes the sockets to be put into
               non-blocking mode which will break Recv::recv().  To
               prevent that issue, I explicitly use the Select Reactor
               instead.  I'll talk more about the "problem" in the Recv
               comments.
             */

            // First, we create a Select_Reactor that will do the work.
            // To keep things simple, I'll create it on the stack.
        ACE_Select_Reactor mySelectReactor;

            // Next, we need an ACE_Reactor that is the bridge between the
            // code and the real reactor.  It is given a pointer to the
            // real reactor.
        ACE_Reactor myReactor (&mySelectReactor);

            // Finally, we set the singleton instance to use the reactor
            // we've created.
        ACE_Reactor::instance (&myReactor);

            // The server object that abstracts away all of the difficult parts.
        Server server;

            // Attempt to open the server.  Like all good ACE-based
            // objects, we'll get -1 on failure.
        if( server.open() == -1 )
        {
            ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "server.open()"), -1);
        }

            // Install a signal handler for ^C so that we can exit gracefully
        ACE_Sig_Action sa ((ACE_SignalHandler) handler, SIGINT);

            // Run the server's main loop until we're interrupted
        if( server.run() == -1 )
        {
            ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "server.run()"), -1);
        }

        return 0;
    }

    /* These explicit instantiations were taken from an earlier tutorial.
       Your compiler may require others as well.
    */
    #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
    template class ACE_Acceptor <Handler, ACE_SOCK_ACCEPTOR>;
    template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>;
    #elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
    #pragma instantiate ACE_Acceptor <Handler, ACE_SOCK_ACCEPTOR>
    #pragma instantiate ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>
    #endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */

[Tutorial Index] [Continue This Tutorial]