Fawkes API
Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * qa_socket_datagram.cpp - Fawkes QA DatagramSocket 00004 * 00005 * Created: Tue Nov 14 11:43:00 2006 00006 * Copyright 2006 Tim Niemueller [www.niemueller.de] 00007 * 00008 ****************************************************************************/ 00009 00010 /* This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. A runtime exception applies to 00014 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Library General Public License for more details. 00020 * 00021 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 00022 */ 00023 00024 /// @cond QA 00025 00026 #include <core/threading/thread.h> 00027 #include <netcomm/socket/datagram.h> 00028 #include <utils/system/signal.h> 00029 00030 #include <netdb.h> 00031 #include <cstdio> 00032 #include <cstring> 00033 #include <netinet/in.h> 00034 00035 using namespace fawkes; 00036 00037 class DatagramServerThread : public Thread 00038 { 00039 public: 00040 DatagramServerThread(unsigned short int port, unsigned int to_port) 00041 : Thread("DatagramServerThread", Thread::OPMODE_CONTINUOUS) 00042 { 00043 i = 0; 00044 s = new DatagramSocket(); 00045 s->bind(port); 00046 00047 struct hostent* h; 00048 00049 h = gethostbyname("127.0.0.1"); 00050 00051 memset(&to, 0, sizeof(to)); 00052 to.sin_family = AF_INET; 00053 memcpy((char *)&to.sin_addr.s_addr, h->h_addr, h->h_length); 00054 to.sin_port = htons(to_port); 00055 00056 } 00057 00058 ~DatagramServerThread() 00059 { 00060 printf("Closing server socket\n"); 00061 s->close(); 00062 printf("Closed server socket\n"); 00063 delete s; 00064 } 00065 00066 virtual void loop() 00067 { 00068 s->send(&i, sizeof(i), (struct sockaddr *)&to, sizeof(to)); 00069 unsigned int ri = 0; 00070 from_len = sizeof(from); 00071 s->recv(&ri, sizeof(ri), (struct sockaddr *)&from, &from_len); 00072 if ( ri != i ) { 00073 printf("ERROR: sent %u but received %u\n", i, ri); 00074 } else { 00075 printf("OK: sent %u and received %u\n", i, ri); 00076 } 00077 ++i; 00078 } 00079 00080 private: 00081 unsigned int i; 00082 DatagramSocket *s; 00083 struct sockaddr_in to; 00084 struct sockaddr_in from; 00085 unsigned int from_len; 00086 }; 00087 00088 00089 class DatagramClientThread : public Thread 00090 { 00091 public: 00092 DatagramClientThread(unsigned short int port, unsigned int to_port) 00093 : Thread("DatagramClientThread", Thread::OPMODE_CONTINUOUS) 00094 { 00095 s = new DatagramSocket(); 00096 s->bind(port); 00097 00098 struct hostent* h; 00099 00100 h = gethostbyname("127.0.0.1"); 00101 00102 memset(&to, 0, sizeof(to)); 00103 to.sin_family = AF_INET; 00104 memcpy((char *)&to.sin_addr.s_addr, h->h_addr, h->h_length); 00105 to.sin_port = htons(to_port); 00106 00107 } 00108 00109 ~DatagramClientThread() 00110 { 00111 printf("Closing server socket\n"); 00112 s->close(); 00113 printf("Closed server socket\n"); 00114 delete s; 00115 } 00116 00117 virtual void loop() 00118 { 00119 unsigned int i = 0; 00120 from_len = sizeof(from); 00121 s->recv(&i, sizeof(i), (struct sockaddr *)&from, &from_len); 00122 s->send(&i, sizeof(i), (struct sockaddr *)&to, sizeof(to)); 00123 } 00124 00125 private: 00126 DatagramSocket *s; 00127 struct sockaddr_in to; 00128 struct sockaddr_in from; 00129 unsigned int from_len; 00130 }; 00131 00132 00133 class DatagramSocketQAMain : public SignalHandler 00134 { 00135 public: 00136 DatagramSocketQAMain() 00137 { 00138 s = new DatagramServerThread(1910, 1911); 00139 c = new DatagramClientThread(1911, 1910); 00140 } 00141 00142 ~DatagramSocketQAMain() 00143 { 00144 delete s; 00145 delete c; 00146 } 00147 00148 00149 virtual void handle_signal(int signum) 00150 { 00151 printf("Signal received, cancelling threads\n"); 00152 s->cancel(); 00153 c->cancel(); 00154 printf("Threads cancelled\n"); 00155 } 00156 00157 void run() 00158 { 00159 s->start(); 00160 c->start(); 00161 s->join(); 00162 c->join(); 00163 } 00164 00165 private: 00166 DatagramServerThread *s; 00167 DatagramClientThread *c; 00168 00169 }; 00170 00171 int 00172 main(int argc, char **argv) 00173 { 00174 DatagramSocketQAMain m; 00175 SignalManager::register_handler(SIGINT, &m); 00176 SignalManager::ignore(SIGPIPE); 00177 00178 m.run(); 00179 } 00180 00181 /// @endcond