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 <utils/system/signal.h>
29 
30 #include <netdb.h>
31 #include <cstdio>
32 #include <cstring>
33 #include <netinet/in.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 
58  ~DatagramServerThread()
59  {
60  printf("Closing server socket\n");
61  s->close();
62  printf("Closed server socket\n");
63  delete s;
64  }
65 
66  virtual void 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 
89 class DatagramClientThread : public Thread
90 {
91 public:
92  DatagramClientThread(unsigned short int port, unsigned int to_port)
93  : Thread("DatagramClientThread", Thread::OPMODE_CONTINUOUS)
94  {
95  s = new DatagramSocket();
96  s->bind(port);
97 
98  struct hostent* h;
99 
100  h = gethostbyname("127.0.0.1");
101 
102  memset(&to, 0, sizeof(to));
103  to.sin_family = AF_INET;
104  memcpy((char *)&to.sin_addr.s_addr, h->h_addr, h->h_length);
105  to.sin_port = htons(to_port);
106 
107  }
108 
109  ~DatagramClientThread()
110  {
111  printf("Closing server socket\n");
112  s->close();
113  printf("Closed server socket\n");
114  delete s;
115  }
116 
117  virtual void loop()
118  {
119  unsigned int i = 0;
120  from_len = sizeof(from);
121  s->recv(&i, sizeof(i), (struct sockaddr *)&from, &from_len);
122  s->send(&i, sizeof(i), (struct sockaddr *)&to, sizeof(to));
123  }
124 
125  private:
126  DatagramSocket *s;
127  struct sockaddr_in to;
128  struct sockaddr_in from;
129  unsigned int from_len;
130 };
131 
132 
133 class DatagramSocketQAMain : public SignalHandler
134 {
135  public:
136  DatagramSocketQAMain()
137  {
138  s = new DatagramServerThread(1910, 1911);
139  c = new DatagramClientThread(1911, 1910);
140  }
141 
142  ~DatagramSocketQAMain()
143  {
144  delete s;
145  delete c;
146  }
147 
148 
149  virtual void handle_signal(int signum)
150  {
151  printf("Signal received, cancelling threads\n");
152  s->cancel();
153  c->cancel();
154  printf("Threads cancelled\n");
155  }
156 
157  void run()
158  {
159  s->start();
160  c->start();
161  s->join();
162  c->join();
163  }
164 
165  private:
166  DatagramServerThread *s;
167  DatagramClientThread *c;
168 
169 };
170 
171 int
172 main(int argc, char **argv)
173 {
174  DatagramSocketQAMain m;
176  SignalManager::ignore(SIGPIPE);
177 
178  m.run();
179 }
180 
181 /// @endcond
Fawkes library namespace.
Interface for signal handling.
Definition: signal.h:35
Thread class encapsulation of pthreads.
Definition: thread.h:42
Datagram socket.
Definition: datagram.h:31
static void ignore(int signum)
Ignore a signal.
Definition: signal.cpp:182
static SignalHandler * register_handler(int signum, SignalHandler *handler)
Register a SignalHandler for a signal.
Definition: signal.cpp:116