Fawkes API  Fawkes Development Version
qa_socket_stream.cpp
1 
2 /***************************************************************************
3  * qa_socket_stream.cpp - Fawkes QA StreamSocket
4  *
5  * Created: Fri Nov 11 14:38:10 2006 (on train back from Google, Hamburg)
6  * Copyright 2006 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version. A runtime exception applies to
14  * this software (see LICENSE.GPL_WRE file mentioned below for details).
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Library General Public License for more details.
20  *
21  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22  */
23 
24 /// @cond QA
25 
26 #include <core/threading/thread.h>
27 #include <netcomm/socket/stream.h>
28 #include <utils/system/argparser.h>
29 #include <utils/system/signal.h>
30 
31 #include <cstdio>
32 
33 using namespace fawkes;
34 
35 class StreamServerThread : public Thread
36 {
37 public:
38  StreamServerThread() : Thread("StreamServerThread", Thread::OPMODE_CONTINUOUS)
39  {
40  i = 0;
41  s = new StreamSocket();
42  s->bind(1910);
43  s->listen();
44  accepted = false;
45  cs = NULL;
46  }
47 
48  ~StreamServerThread()
49  {
50  printf("Closing server socket\n");
51  s->close();
52  if (cs)
53  cs->close();
54  printf("Closed server socket\n");
55  delete s;
56  delete cs;
57  }
58 
59  virtual void
60  loop()
61  {
62  if (!accepted) {
63  try {
64  cs = s->accept();
65  accepted = true;
66  printf("Server MTU: %u\n", cs->mtu());
67  } catch (SocketException &e) {
68  e.print_trace();
69  }
70  }
71  if (accepted) {
72  try {
73  cs->write(&i, sizeof(i));
74  unsigned int ri = 0;
75  cs->read(&ri, sizeof(ri));
76  if (ri != i) {
77  printf("ERROR: sent %u but received %u\n", i, ri);
78  } else {
79  printf("OK: sent %u and received %u\n", i, ri);
80  }
81  ++i;
82  } catch (SocketException &e) {
83  e.print_trace();
84  printf("Loop failed, disconnecting and waiting for new connection\n");
85  delete cs;
86  cs = NULL;
87  accepted = false;
88  }
89  }
90  }
91 
92 private:
93  unsigned int i;
94  StreamSocket *s;
95  Socket * cs;
96  bool accepted;
97 };
98 
99 class StreamClientThread : public Thread
100 {
101 public:
102  StreamClientThread(const char *host) : Thread("StreamClientThread", Thread::OPMODE_CONTINUOUS)
103  {
104  if (host == NULL) {
105  this->host = "127.0.0.1";
106  } else {
107  this->host = host;
108  }
109 
110  s = new StreamSocket();
111  connected = false;
112  }
113 
114  ~StreamClientThread()
115  {
116  printf("Closing client socket\n");
117  s->close();
118  printf("Closed client socket\n");
119  delete s;
120  }
121 
122  virtual void
123  loop()
124  {
125  if (!connected) {
126  try {
127  s->connect(host, 1910);
128  connected = true;
129  printf("Client MTU: %u\n", s->mtu());
130  } catch (SocketException &e) {
131  e.print_trace();
132  }
133  }
134  if (connected) {
135  unsigned int i = 0;
136  s->read(&i, sizeof(i));
137  s->write(&i, sizeof(i));
138  }
139  }
140 
141 private:
142  const char * host;
143  StreamSocket *s;
144  bool connected;
145 };
146 
147 class StreamSocketQAMain : public SignalHandler
148 {
149 public:
150  static const unsigned int MODE_STANDALONE = 1;
151  static const unsigned int MODE_SERVER = 2;
152  static const unsigned int MODE_CLIENT = 3;
153 
154  StreamSocketQAMain(unsigned int mode, const char *host = NULL)
155  {
156  s = NULL;
157  c = NULL;
158  if ((mode == MODE_STANDALONE) || (mode == MODE_SERVER)) {
159  s = new StreamServerThread();
160  }
161  if ((mode == MODE_STANDALONE) || (mode == MODE_CLIENT)) {
162  c = new StreamClientThread(host);
163  }
164  }
165 
166  ~StreamSocketQAMain()
167  {
168  delete s;
169  delete c;
170  }
171 
172  virtual void
173  handle_signal(int signum)
174  {
175  printf("Signal received, cancelling threads\n");
176  if (s)
177  s->cancel();
178  if (c)
179  c->cancel();
180  printf("Threads cancelled\n");
181  }
182 
183  void
184  run()
185  {
186  if (s)
187  s->start();
188  if (c)
189  c->start();
190  if (s)
191  s->join();
192  if (c)
193  c->join();
194  }
195 
196 private:
197  StreamServerThread *s;
198  StreamClientThread *c;
199 };
200 
201 int
202 main(int argc, char **argv)
203 {
204  StreamSocketQAMain *m;
205  SignalManager::ignore(SIGPIPE);
206 
207  ArgumentParser argp(argc, argv, "sc:");
208 
209  if (argp.has_arg("s") || argp.has_arg("c")) {
210  // Special mode
211  if (argp.has_arg("s")) {
212  // Only run Server
213  m = new StreamSocketQAMain(StreamSocketQAMain::MODE_SERVER);
214  } else {
215  m = new StreamSocketQAMain(StreamSocketQAMain::MODE_CLIENT, argp.arg("c"));
216  }
217  } else {
218  m = new StreamSocketQAMain(StreamSocketQAMain::MODE_STANDALONE);
219  }
220 
222 
223  m->run();
224  delete m;
225 
227 }
228 
229 /// @endcond
fawkes::SocketException
Definition: socket.h:60
fawkes::SignalHandler
Definition: signal.h:43
fawkes::SignalManager::finalize
static void finalize()
Finalize (and free) the SignalManager instance, this does NOT implicitly delete the signal handlers,...
Definition: signal.cpp:104
fawkes::SignalManager::ignore
static void ignore(int signum)
Ignore a signal.
Definition: signal.cpp:182
fawkes::SignalManager::register_handler
static SignalHandler * register_handler(int signum, SignalHandler *handler)
Register a SignalHandler for a signal.
Definition: signal.cpp:121
fawkes
fawkes::ArgumentParser
Definition: argparser.h:67
fawkes::Exception::print_trace
void print_trace()
Prints trace to stderr.
Definition: exception.cpp:600
fawkes::Thread
Definition: thread.h:44
fawkes::StreamSocket
Definition: stream.h:35
fawkes::Socket
Definition: socket.h:67