Fawkes API  Fawkes Development Version
qa_socket_datagram_broadcast.cpp
1 
2 /***************************************************************************
3  * qa_socket_datagram_broadcast.cpp - Fawkes QA BroadcastDatagramSocket
4  *
5  * Created: Fri 02 Apr 2010 03:15:49 PM CEST
6  * Copyright 2006-2007 Tim Niemueller [www.niemueller.de]
7  * Copyright 2010 Christoph Schwering (copied from Tim's
8  * qa_socket_datagram_multicast.cpp)
9  *
10  ****************************************************************************/
11 
12 /* This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version. A runtime exception applies to
16  * this software (see LICENSE.GPL_WRE file mentioned below for details).
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU Library General Public License for more details.
22  *
23  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
24  */
25 
26 /// @cond QA
27 
28 /* NOTE:
29  * This program does not do any error correction, if a number is not received
30  * by the reflector, this may stall. On wireless networks this is usually
31  * the case for an i << 100, often even i < 10. If you use a cable connection
32  * this problem does not occur. Meaning that the connection stalls is not an
33  * indicator for a broken implementation, as long as you can do this with a
34  * reliable connection like a cabled LAN for a long time (stopped my tests
35  * at i ~ 1000).
36  */
37 
38 
39 #include <core/threading/thread.h>
40 #include <netcomm/socket/datagram_broadcast.h>
41 #include <utils/system/signal.h>
42 #include <utils/system/argparser.h>
43 
44 #include <netdb.h>
45 #include <cstdio>
46 #include <cstring>
47 #include <netinet/in.h>
48 
49 #define BROADCAST_IP "172.16.35.255"
50 
51 using namespace fawkes;
52 
53 class BroadcastDatagramServerThread : public Thread
54 {
55 public:
56  BroadcastDatagramServerThread(unsigned short int port)
57  : Thread("BroadcastDatagramServerThread", Thread::OPMODE_CONTINUOUS)
58  {
59  i = 0;
60  try {
61  s = new BroadcastDatagramSocket(BROADCAST_IP, port);
62  s->bind();
63  } catch (Exception &e) {
64  e.print_trace();
65  throw;
66  }
67  }
68 
69  ~BroadcastDatagramServerThread()
70  {
71  printf("Closing server socket\n");
72  s->close();
73  printf("Closed server socket\n");
74  delete s;
75  }
76 
77  virtual void loop()
78  {
79  try {
80  printf("Sending %u\n", i);
81  s->send(&i, sizeof(i));
82  printf("Sent %u\n", i);
83  unsigned int ri = 0;
84  from_len = sizeof(from);
85  printf("Receiving\n");
86  s->recv(&ri, sizeof(ri), (struct sockaddr *)&from, &from_len);
87  if ( ri != i ) {
88  printf("ERROR: sent %u but received %u\n", i, ri);
89  } else {
90  printf("OK: sent %u and received %u\n", i, ri);
91  }
92  ++i;
93  } catch (Exception &e) {
94  printf("Loop failed\n");
95  e.print_trace();
96  throw;
97  }
98  }
99 
100  private:
101  unsigned int i;
103  struct sockaddr_in from;
104  unsigned int from_len;
105 };
106 
107 class BroadcastDatagramReflectorThread : public Thread
108 {
109 public:
110  BroadcastDatagramReflectorThread(unsigned short int port)
111  : Thread("BroadcastDatagramReflectorThread", Thread::OPMODE_CONTINUOUS)
112  {
113  try {
114  s = new BroadcastDatagramSocket("224.16.0.1", port);
115  s->bind();
116  } catch (Exception &e) {
117  e.print_trace();
118  throw;
119  }
120  from_len = sizeof(from);
121  }
122 
123  ~BroadcastDatagramReflectorThread()
124  {
125  printf("Closing reflector socket\n");
126  s->close();
127  printf("Closed reflector socket\n");
128  delete s;
129  }
130 
131  virtual void loop()
132  {
133  unsigned int i = 0;
134  printf("Waiting for data to reflect\n");
135  s->recv(&i, sizeof(i), (struct sockaddr *)&from, &from_len);
136  printf("Received %u, reflecting\n", i);
137  s->send(&i, sizeof(i));
138  }
139 
140  private:
142  struct sockaddr_in from;
143  unsigned int from_len;
144 };
145 
146 
147 class BroadcastDatagramSocketQAMain : public SignalHandler
148 {
149  public:
150  BroadcastDatagramSocketQAMain(ArgumentParser& argp)
151  {
152  s = NULL;
153  r = NULL;
154  if ( argp.has_arg("r") ) {
155  printf("Going to be a reflector\n");
156  r = new BroadcastDatagramReflectorThread(1910);
157  } else {
158  s = new BroadcastDatagramServerThread(1910);
159  }
160  }
161 
162  ~BroadcastDatagramSocketQAMain()
163  {
164  delete s;
165  delete r;
166  }
167 
168 
169  virtual void handle_signal(int signum)
170  {
171  printf("Signal received, cancelling threads\n");
172  if ( s != NULL ) s->cancel();
173  if ( r != NULL ) r->cancel();
174  printf("Threads cancelled\n");
175  }
176 
177  void run()
178  {
179  if ( s != NULL ) {
180  s->start();
181  s->join();
182  }
183  if ( r != NULL ) {
184  r->start();
185  r->join();
186  }
187  }
188 
189  private:
190  BroadcastDatagramServerThread *s;
191  BroadcastDatagramReflectorThread *r;
192 
193 };
194 
195 int
196 main(int argc, char **argv)
197 {
198  printf("Going to broadcast to " BROADCAST_IP "\n");
199  ArgumentParser argp(argc, argv, "r");
200  BroadcastDatagramSocketQAMain m(argp);
202  SignalManager::ignore(SIGPIPE);
203 
204  m.run();
205  return 0;
206 }
207 
208 /// @endcond
Fawkes library namespace.
Interface for signal handling.
Definition: signal.h:35
Parse command line arguments.
Definition: argparser.h:66
Thread class encapsulation of pthreads.
Definition: thread.h:42
Base class for exceptions in Fawkes.
Definition: exception.h:36
Broadcast datagram socket.
static void ignore(int signum)
Ignore a signal.
Definition: signal.cpp:182
static SignalHandler * register_handler(int signum, SignalHandler *handler)
Register a SignalHandler for a signal.
Definition: signal.cpp:116
void print_trace()
Prints trace to stderr.
Definition: exception.cpp:619
bool has_arg(const char *argn)
Check if argument has been supplied.
Definition: argparser.cpp:169