Fawkes API  Fawkes Development Version
qa_socket_datagram.cpp
1 
2 /***************************************************************************
3  * qa_socket_datagram.cpp - Fawkes QA DatagramSocket
4  *
5  * Created: Tue Nov 14 11:43:00 2006
6  * Copyright 2006 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version. A runtime exception applies to
14  * this software (see LICENSE.GPL_WRE file mentioned below for details).
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Library General Public License for more details.
20  *
21  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22  */
23 
24 /// @cond QA
25 
26 #include <core/threading/thread.h>
27 #include <netcomm/socket/datagram.h>
28 #include <netinet/in.h>
29 #include <utils/system/signal.h>
30 
31 #include <cstdio>
32 #include <cstring>
33 #include <netdb.h>
34 
35 using namespace fawkes;
36 
37 class DatagramServerThread : public Thread
38 {
39 public:
40  DatagramServerThread(unsigned short int port, unsigned int to_port)
41  : Thread("DatagramServerThread", Thread::OPMODE_CONTINUOUS)
42  {
43  i = 0;
44  s = new DatagramSocket();
45  s->bind(port);
46 
47  struct hostent *h;
48 
49  h = gethostbyname("127.0.0.1");
50 
51  memset(&to, 0, sizeof(to));
52  to.sin_family = AF_INET;
53  memcpy((char *)&to.sin_addr.s_addr, h->h_addr, h->h_length);
54  to.sin_port = htons(to_port);
55  }
56 
57  ~DatagramServerThread()
58  {
59  printf("Closing server socket\n");
60  s->close();
61  printf("Closed server socket\n");
62  delete s;
63  }
64 
65  virtual void
66  loop()
67  {
68  s->send(&i, sizeof(i), (struct sockaddr *)&to, sizeof(to));
69  unsigned int ri = 0;
70  from_len = sizeof(from);
71  s->recv(&ri, sizeof(ri), (struct sockaddr *)&from, &from_len);
72  if (ri != i) {
73  printf("ERROR: sent %u but received %u\n", i, ri);
74  } else {
75  printf("OK: sent %u and received %u\n", i, ri);
76  }
77  ++i;
78  }
79 
80 private:
81  unsigned int i;
82  DatagramSocket * s;
83  struct sockaddr_in to;
84  struct sockaddr_in from;
85  unsigned int from_len;
86 };
87 
88 class DatagramClientThread : public Thread
89 {
90 public:
91  DatagramClientThread(unsigned short int port, unsigned int to_port)
92  : Thread("DatagramClientThread", Thread::OPMODE_CONTINUOUS)
93  {
94  s = new DatagramSocket();
95  s->bind(port);
96 
97  struct hostent *h;
98 
99  h = gethostbyname("127.0.0.1");
100 
101  memset(&to, 0, sizeof(to));
102  to.sin_family = AF_INET;
103  memcpy((char *)&to.sin_addr.s_addr, h->h_addr, h->h_length);
104  to.sin_port = htons(to_port);
105  }
106 
107  ~DatagramClientThread()
108  {
109  printf("Closing server socket\n");
110  s->close();
111  printf("Closed server socket\n");
112  delete s;
113  }
114 
115  virtual void
116  loop()
117  {
118  unsigned int i = 0;
119  from_len = sizeof(from);
120  s->recv(&i, sizeof(i), (struct sockaddr *)&from, &from_len);
121  s->send(&i, sizeof(i), (struct sockaddr *)&to, sizeof(to));
122  }
123 
124 private:
125  DatagramSocket * s;
126  struct sockaddr_in to;
127  struct sockaddr_in from;
128  unsigned int from_len;
129 };
130 
131 class DatagramSocketQAMain : public SignalHandler
132 {
133 public:
134  DatagramSocketQAMain()
135  {
136  s = new DatagramServerThread(1910, 1911);
137  c = new DatagramClientThread(1911, 1910);
138  }
139 
140  ~DatagramSocketQAMain()
141  {
142  delete s;
143  delete c;
144  }
145 
146  virtual void
147  handle_signal(int signum)
148  {
149  printf("Signal received, cancelling threads\n");
150  s->cancel();
151  c->cancel();
152  printf("Threads cancelled\n");
153  }
154 
155  void
156  run()
157  {
158  s->start();
159  c->start();
160  s->join();
161  c->join();
162  }
163 
164 private:
165  DatagramServerThread *s;
166  DatagramClientThread *c;
167 };
168 
169 int
170 main(int argc, char **argv)
171 {
172  DatagramSocketQAMain m;
174  SignalManager::ignore(SIGPIPE);
175 
176  m.run();
177 }
178 
179 /// @endcond
Fawkes library namespace.
Interface for signal handling.
Definition: signal.h:35
Thread class encapsulation of pthreads.
Definition: thread.h:45
Datagram socket.
Definition: datagram.h:31
static void ignore(int signum)
Ignore a signal.
Definition: signal.cpp:174
static SignalHandler * register_handler(int signum, SignalHandler *handler)
Register a SignalHandler for a signal.
Definition: signal.cpp:113