summaryrefslogtreecommitdiff
path: root/docs/tutorials/001/server.cpp
blob: 391b1c18825fa9192233336c43727d593a9f4c33 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

// $Id$


/*
  Include the header file where our client acceptor is defined.
 */
#include "ace/Reactor.h"

/*  
  For simplicity, we create our reactor in the global address space.
  In later tutorials we will do something more clever and appropriate. However,
  the purpose of this tutorial is to introduce a connection acceptance and
  handling, not the full capabilities of a reactor.
*/
ACE_Reactor * g_reactor;

/*
  Include the header where we define our acceptor object.  An acceptor is
  an abstraction that allows a server to "accept" connections from clients.
*/
#include "acceptor.h"

/*
  A TCP/IP server can listen to only one port for connection requests.
  Well-known services can always be found at the same address. Lesser-known
  services are generally told where to listen by a configuration file or
  command-line parameter. For this example, we're satisfied with simply hard-coding
  a random but known value.
*/
static const u_short PORT = ACE_DEFAULT_SERVER_PORT;

int main (int, char **)
{
  /*
    Create a Reactor instance.  Again, a global pointer isn't exactly the
    best way to handle this but for the simple example here, it will be OK.
    We'll get cute with it later.
  */
  g_reactor = new ACE_Reactor;

  /*
    Like the Reactor, I'm skimming over the details of the ADDR
    object. What it provides is an abstraction for addressing services in the
    network. All we need to know at this point is that we are creating an address
    object which specifies the TCP/IP port on which the server
    will listen for new connection requests.
  */
  ACE_INET_Addr addr (PORT);

  /*
    We now create an acceptor object.  No connections will
    yet be established because the object isn't "open for business"
    at this time. Which brings us to the next line...
  */
  Logging_Acceptor * peer_acceptor = new Logging_Acceptor();

  /*
    where the acceptor object is opened.  You'll find that most ACE
    objects have to be open()ed before they're of any use to you.
    On this open() call, we're telling the acceptor where to listen
    for connections via the 'addr' object.  We're also telling it
    that we want it to be registered with our 'g_reactor' instance.
   */
  if (peer_acceptor->open(addr,g_reactor) == -1 )
    ACE_ERROR_RETURN ((LM_ERROR, "Opening Acceptor\n"), -1);

  ACE_DEBUG ((LM_DEBUG, "(%P|%t) starting up server logging daemon\n"));

  /*
    The reactor's handle_events member function is responsible for looking at
    all registered objects and invoking an appropriate member function when
    anything of interest occurs. When an event is processed, the handle_events
    function returns. In order to get all events, we embed this in an infinite
    loop.

    Since we put ourselves into an infinite loop, you'll need to CTRL-C
    to exit the program.
  */
  while (1)
     g_reactor-> handle_events ();

  return 0;
}