qa_socket_datagram_broadcast.cpp

00001 
00002 /***************************************************************************
00003  *  qa_socket_datagram_broadcast.cpp - Fawkes QA BroadcastDatagramSocket
00004  *
00005  *  Created: Fri 02 Apr 2010 03:15:49 PM CEST
00006  *  Copyright  2006-2007  Tim Niemueller [www.niemueller.de]
00007  *  Copyright  2010  Christoph Schwering (copied from Tim's
00008  *  qa_socket_datagram_multicast.cpp)
00009  *
00010  ****************************************************************************/
00011 
00012 /*  This program is free software; you can redistribute it and/or modify
00013  *  it under the terms of the GNU General Public License as published by
00014  *  the Free Software Foundation; either version 2 of the License, or
00015  *  (at your option) any later version. A runtime exception applies to
00016  *  this software (see LICENSE.GPL_WRE file mentioned below for details).
00017  *
00018  *  This program is distributed in the hope that it will be useful,
00019  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021  *  GNU Library General Public License for more details.
00022  *
00023  *  Read the full text in the LICENSE.GPL_WRE file in the doc directory.
00024  */
00025 
00026 /// @cond QA
00027 
00028 /* NOTE:
00029  * This program does not do any error correction, if a number is not received
00030  * by the reflector, this may stall. On wireless networks this is usually
00031  * the case for an i << 100, often even i < 10. If you use a cable connection
00032  * this problem does not occur. Meaning that the connection stalls is not an
00033  * indicator for a broken implementation, as long as you can do this with a
00034  * reliable connection like a cabled LAN for a long time (stopped my tests
00035  * at i ~ 1000).
00036  */
00037 
00038 
00039 #include <core/threading/thread.h>
00040 #include <netcomm/socket/datagram_broadcast.h>
00041 #include <utils/system/signal.h>
00042 #include <utils/system/argparser.h>
00043 
00044 #include <netdb.h>
00045 #include <cstdio>
00046 #include <cstring>
00047 #include <netinet/in.h>
00048 
00049 #define BROADCAST_IP "172.16.35.255"
00050 
00051 using namespace fawkes;
00052 
00053 class BroadcastDatagramServerThread : public Thread
00054 {
00055 public:
00056   BroadcastDatagramServerThread(unsigned short int port)
00057     : Thread("BroadcastDatagramServerThread", Thread::OPMODE_CONTINUOUS)
00058   {
00059     i = 0;
00060     try {
00061       s = new BroadcastDatagramSocket(BROADCAST_IP, port);
00062       s->bind();
00063     } catch (Exception &e) {
00064       e.print_trace();
00065       throw;
00066     }
00067   }
00068 
00069   ~BroadcastDatagramServerThread()
00070   {
00071     printf("Closing server socket\n");
00072     s->close();
00073     printf("Closed server socket\n");
00074     delete s;
00075   }
00076 
00077   virtual void loop()
00078   {
00079     try {
00080       printf("Sending %u\n", i);
00081       s->send(&i, sizeof(i));
00082       printf("Sent %u\n", i);
00083       unsigned int ri = 0;
00084       from_len = sizeof(from);
00085       printf("Receiving\n");
00086       s->recv(&ri, sizeof(ri), (struct sockaddr *)&from, &from_len);
00087       if ( ri != i ) {
00088         printf("ERROR: sent %u but received %u\n", i, ri);
00089       } else {
00090         printf("OK: sent %u and received %u\n", i, ri);
00091       }
00092       ++i;
00093     } catch (Exception &e) {
00094       printf("Loop failed\n");
00095       e.print_trace();
00096       throw;
00097     }
00098   }
00099 
00100  private:
00101   unsigned int i;
00102   BroadcastDatagramSocket *s;
00103   struct sockaddr_in from;
00104   unsigned int from_len;
00105 };
00106 
00107 class BroadcastDatagramReflectorThread : public Thread
00108 {
00109 public:
00110   BroadcastDatagramReflectorThread(unsigned short int port)
00111     : Thread("BroadcastDatagramReflectorThread", Thread::OPMODE_CONTINUOUS)
00112   {
00113     try {
00114       s = new BroadcastDatagramSocket("224.16.0.1", port);
00115       s->bind();
00116     } catch (Exception &e) {
00117       e.print_trace();
00118       throw;
00119     }
00120     from_len = sizeof(from);
00121   }
00122 
00123   ~BroadcastDatagramReflectorThread()
00124   {
00125     printf("Closing reflector socket\n");
00126     s->close();
00127     printf("Closed reflector socket\n");
00128     delete s;
00129   }
00130 
00131   virtual void loop()
00132   {
00133     unsigned int i = 0;
00134     printf("Waiting for data to reflect\n");
00135     s->recv(&i, sizeof(i), (struct sockaddr *)&from, &from_len);
00136     printf("Received %u, reflecting\n", i);
00137     s->send(&i, sizeof(i));
00138   }
00139 
00140  private:
00141   BroadcastDatagramSocket *s;
00142   struct sockaddr_in from;
00143   unsigned int from_len;
00144 };
00145 
00146 
00147 class BroadcastDatagramSocketQAMain : public SignalHandler
00148 {
00149  public:
00150   BroadcastDatagramSocketQAMain(ArgumentParser& argp)
00151   {
00152     s = NULL;
00153     r = NULL;
00154     if ( argp.has_arg("r") ) {
00155       printf("Going to be a reflector\n");
00156       r = new BroadcastDatagramReflectorThread(1910);
00157     } else {
00158       s = new BroadcastDatagramServerThread(1910);
00159     }
00160   }
00161 
00162   ~BroadcastDatagramSocketQAMain()
00163   {
00164     delete s;
00165     delete r;
00166   }
00167 
00168 
00169   virtual void handle_signal(int signum)
00170   {
00171     printf("Signal received, cancelling threads\n");
00172     if ( s != NULL )  s->cancel();
00173     if ( r != NULL )  r->cancel();
00174     printf("Threads cancelled\n");
00175   }
00176 
00177   void run()
00178   {
00179     if ( s != NULL ) {
00180       s->start();
00181       s->join();
00182     }
00183     if ( r != NULL ) {
00184       r->start();
00185       r->join();
00186     }
00187   }
00188 
00189  private:
00190   BroadcastDatagramServerThread *s;
00191   BroadcastDatagramReflectorThread *r;
00192 
00193 };
00194 
00195 int
00196 main(int argc, char **argv)
00197 {
00198   printf("Going to broadcast to " BROADCAST_IP "\n");
00199   ArgumentParser argp(argc, argv, "r");
00200   BroadcastDatagramSocketQAMain m(argp);
00201   SignalManager::register_handler(SIGINT, &m);
00202   SignalManager::ignore(SIGPIPE);
00203 
00204   m.run();
00205   return 0;
00206 }
00207 
00208 /// @endcond

Generated on 1 Mar 2011 for Fawkes API by  doxygen 1.6.1