00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include <core/threading/thread.h>
00038 #include <netcomm/socket/datagram_multicast.h>
00039 #include <utils/system/signal.h>
00040 #include <utils/system/argparser.h>
00041
00042 #include <netdb.h>
00043 #include <cstdio>
00044 #include <cstring>
00045 #include <netinet/in.h>
00046
00047 using namespace fawkes;
00048
00049 class MulticastDatagramServerThread : public Thread
00050 {
00051 public:
00052 MulticastDatagramServerThread(unsigned short int port, bool looping)
00053 : Thread("MulticastDatagramServerThread", Thread::OPMODE_CONTINUOUS)
00054 {
00055 i = 0;
00056 try {
00057 s = new MulticastDatagramSocket("224.16.0.1", port);
00058 s->bind();
00059 s->set_loop(looping);
00060 } catch (Exception &e) {
00061 e.print_trace();
00062 throw;
00063 }
00064 }
00065
00066 ~MulticastDatagramServerThread()
00067 {
00068 printf("Closing server socket\n");
00069 s->close();
00070 printf("Closed server socket\n");
00071 delete s;
00072 }
00073
00074 virtual void loop()
00075 {
00076 try {
00077 printf("Sending %u\n", i);
00078 s->send(&i, sizeof(i));
00079 printf("Sent %u\n", i);
00080 unsigned int ri = 0;
00081 from_len = sizeof(from);
00082 printf("Receiving\n");
00083 s->recv(&ri, sizeof(ri), (struct sockaddr *)&from, &from_len);
00084 if ( ri != i ) {
00085 printf("ERROR: sent %u but received %u\n", i, ri);
00086 } else {
00087 printf("OK: sent %u and received %u\n", i, ri);
00088 }
00089 ++i;
00090 } catch (Exception &e) {
00091 printf("Loop failed\n");
00092 e.print_trace();
00093 throw;
00094 }
00095 }
00096
00097 private:
00098 unsigned int i;
00099 MulticastDatagramSocket *s;
00100 struct sockaddr_in from;
00101 unsigned int from_len;
00102 };
00103
00104 class MulticastDatagramReflectorThread : public Thread
00105 {
00106 public:
00107 MulticastDatagramReflectorThread(unsigned short int port)
00108 : Thread("MulticastDatagramReflectorThread", Thread::OPMODE_CONTINUOUS)
00109 {
00110 try {
00111 s = new MulticastDatagramSocket("224.16.0.1", port);
00112 s->bind();
00113 } catch (Exception &e) {
00114 e.print_trace();
00115 throw;
00116 }
00117 from_len = sizeof(from);
00118 }
00119
00120 ~MulticastDatagramReflectorThread()
00121 {
00122 printf("Closing reflector socket\n");
00123 s->close();
00124 printf("Closed reflector socket\n");
00125 delete s;
00126 }
00127
00128 virtual void loop()
00129 {
00130 unsigned int i = 0;
00131 printf("Waiting for data to reflect\n");
00132 s->recv(&i, sizeof(i), (struct sockaddr *)&from, &from_len);
00133 printf("Received %u, reflecting\n", i);
00134 s->send(&i, sizeof(i));
00135 }
00136
00137 private:
00138 MulticastDatagramSocket *s;
00139 struct sockaddr_in from;
00140 unsigned int from_len;
00141 };
00142
00143
00144 class MulticastDatagramSocketQAMain : public SignalHandler
00145 {
00146 public:
00147 MulticastDatagramSocketQAMain(ArgumentParser *argp)
00148 {
00149 s = NULL;
00150 r = NULL;
00151 this->argp = argp;
00152 if ( argp->has_arg("r") ) {
00153 printf("Going to be a reflector\n");
00154 r = new MulticastDatagramReflectorThread(1910);
00155 } else {
00156 bool looping = argp->has_arg("l");
00157 if ( looping ) {
00158 printf("Enabling local loop (we receive own traffic)\n");
00159 }
00160 s = new MulticastDatagramServerThread(1910, looping);
00161 }
00162 }
00163
00164 ~MulticastDatagramSocketQAMain()
00165 {
00166 delete s;
00167 delete r;
00168 }
00169
00170
00171 virtual void handle_signal(int signum)
00172 {
00173 printf("Signal received, cancelling threads\n");
00174 if ( s != NULL ) s->cancel();
00175 if ( r != NULL ) r->cancel();
00176 printf("Threads cancelled\n");
00177 }
00178
00179 void run()
00180 {
00181 if ( s != NULL ) {
00182 s->start();
00183 s->join();
00184 }
00185 if ( r != NULL ) {
00186 r->start();
00187 r->join();
00188 }
00189 }
00190
00191 private:
00192 ArgumentParser *argp;
00193 MulticastDatagramServerThread *s;
00194 MulticastDatagramReflectorThread *r;
00195
00196 };
00197
00198 int
00199 main(int argc, char **argv)
00200 {
00201 ArgumentParser *argp = new ArgumentParser(argc, argv, "rl");
00202
00203 MulticastDatagramSocketQAMain m(argp);
00204 SignalManager::register_handler(SIGINT, &m);
00205 SignalManager::ignore(SIGPIPE);
00206
00207 m.run();
00208
00209 delete argp;
00210 return 0;
00211 }
00212
00213