summaryrefslogtreecommitdiff
path: root/examples/ASX/Event_Server/Transceiver/transceiver.cpp
blob: 37335b8209f7508ede6979d4dd1cf585d57c55cf (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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
// Test program for the event transceiver.  This program can play the
// $Id$

// role of either Consumer or Supplier.  You can terminate this
// program by typing ^C....


#include "ace/Service_Config.h"
#include "ace/Connector.h"
#include "ace/SOCK_Connector.h"
#include "ace/Get_Opt.h"

#if defined (ACE_HAS_THREADS)

class Event_Transceiver : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>
  // = TITLE
  //     Generate and receives messages from the event server.
  // 
  // = DESCRIPTION
  //     This class is both a consumer and supplier of events, i.e.,
  //     it is a ``transceiver.''
{
public:
  Event_Transceiver (void);

  // = Svc_Handler hook called by the <ACE_Connector>.
  virtual int open (void *);
  // Initialize the transceiver when we are connected.

  // = Demultplexing hooks from the <ACE_Reactor>.
  virtual int handle_input (ACE_HANDLE);
  // Receive data from STDIN or socket.

  virtual int handle_signal (int signum, siginfo_t *, ucontext_t *);
  // Close down via SIGINT.

private:
  int receiver (void);
  // Reads data from socket and writes to ACE_STDOUT.

  int forwarder (void);
  // Writes data from ACE_STDIN to socket.
};

// Close down via SIGINT.

int 
Event_Transceiver::handle_signal (int signum, 
				       siginfo_t *, 
				       ucontext_t *)
{
  ACE_DEBUG ((LM_DEBUG, "(%P|%t) received signal %S\n", signum));
  
  ACE_Service_Config::end_reactor_event_loop ();
  return 0;
}

Event_Transceiver::Event_Transceiver (void)
{
  ACE_Sig_Set sig_set;
  
  sig_set.sig_add (SIGINT);
  sig_set.sig_add (SIGQUIT);

  if (ACE_Service_Config::reactor ()->register_handler 
      (sig_set, this) == -1)
    ACE_ERROR ((LM_ERROR, "%p\n", "register_handler"));
}

int
Event_Transceiver::open (void *)
{
  if (ACE_Service_Config::reactor ()->register_handler
      (this->peer ().get_handle (), 
       this,
       ACE_Event_Handler::READ_MASK) == -1)
    ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "register_handler"), -1);
  else if (ACE::register_stdin_handler (this,
					ACE_Service_Config::reactor (),
					ACE_Service_Config::thr_mgr ()) == -1)
    ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "register_stdin_handler"), -1);
  return 0;
}

int
Event_Transceiver::handle_input (ACE_HANDLE handle)
{
  if (handle == ACE_STDIN)
    return this->forwarder ();
  else
    return this->receiver ();
}


int
Event_Transceiver::forwarder (void)
{
  ACE_DEBUG ((LM_DEBUG, "(%P|%t) entering transceiver forwarder\n"));

  char buf[BUFSIZ];
  ssize_t n = ACE_OS::read (ACE_STDIN, buf, sizeof buf);
  int result = 0;

  if (n <= 0 || this->peer ().send_n (buf, n) != n)
    result = -1;

  ACE_DEBUG ((LM_DEBUG, "(%P|%t) leaving transceiver forwarder\n"));
  return result;
}

int
Event_Transceiver::receiver (void)
{
  ACE_DEBUG ((LM_DEBUG, "(%P|%t) entering transceiver receiver\n"));

  char buf[BUFSIZ];

  ssize_t n = this->peer ().recv (buf, sizeof buf);
  int result = 0;

  if (n <= 0 || ACE_OS::write (ACE_STDOUT, buf, n) != n)
    result = -1;

  ACE_DEBUG ((LM_DEBUG, "(%P|%t) leaving transceiver receiver\n"));
  return result;
}

// Port number of event server.
static u_short port_number;

// Name of event server.
static char *host_name;

// Handle the command-line arguments.

static void 
parse_args (int argc, char *argv[])
{
  ACE_Get_Opt get_opt (argc, argv, "h:p:");

  port_number = ACE_DEFAULT_SERVER_PORT;
  host_name = ACE_DEFAULT_SERVER_HOST;

  for (int c; (c = get_opt ()) != -1; )
    switch (c)
      {
      case 'h':
	host_name = get_opt.optarg;
	break;
      case 'p':
	port_number = ACE_OS::atoi (get_opt.optarg);
	break;
      default:
	ACE_ERROR ((LM_ERROR, 
		    "usage: %n [-p portnum] [-h host_name]\n%a", 1));
	/* NOTREACHED */
	break;
      }
}

int 
main (int argc, char *argv[]) 
{ 
  ACE_Service_Config daemon (argv[0]);

  parse_args (argc, argv);

  // Establish the connection.
  ACE_Connector<Event_Transceiver, ACE_SOCK_CONNECTOR> connector;
  Event_Transceiver transceiver;

  if (connector.connect (&transceiver, ACE_INET_Addr (port_number, host_name)) == -1)
    ACE_ERROR_RETURN ((LM_ERROR, "%p\n", host_name), 1);

  // Run event loop until either the event server shuts down or we get
  // a SIGINT.
  ACE_Service_Config::run_reactor_event_loop ();
  return 0;
}
#else
int 
main (void)
{
  ACE_ERROR ((LM_ERROR, "test not defined for this platform\n"));
  return 0;
}
#endif /* ACE_HAS_THREADS */