Fawkes API
Fawkes Development Version
|
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