IBR-DTNSuite  0.12
socket.h
Go to the documentation of this file.
1 /*
2  * socket.h
3  *
4  * Copyright (C) 2011 IBR, TU Braunschweig
5  *
6  * Written-by: Johannes Morgenroth <morgenroth@ibr.cs.tu-bs.de>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21 
22 #ifndef IBRCOMMON_SOCKET_H_
23 #define IBRCOMMON_SOCKET_H_
24 
25 #include <ibrcommon/Exceptions.h>
26 #include <ibrcommon/data/File.h>
27 #include <ibrcommon/net/vaddress.h>
29 #include <sstream>
30 #include <string.h>
31 #include <sys/time.h>
32 
33 #ifdef __WIN32__
34 #include <winsock2.h>
35 #include <ws2tcpip.h>
36 #else
37 #include <sys/socket.h>
38 #endif
39 
40 namespace ibrcommon {
42  {
50  };
51 
52  class socket_exception : public Exception
53  {
54  public:
56  {};
57 
58  socket_exception(string error) : Exception(error)
59  {};
60  };
61 
63  {
64  public:
65  socket_error(socket_error_code code, string error) : socket_exception(error), _code(code)
66  {};
67 
68  socket_error_code code() const { return _code; }
69 
70  private:
71  socket_error_code _code;
72  };
73 
75  {
76  public:
77  socket_raw_error(int error, string description) : socket_exception(description), _errno(error)
78  {
79  std::stringstream ss;
80  ss << error << ": " << socket_exception::what();
81  __what = ss.str();
82  };
83 
84  socket_raw_error(int error) : socket_exception(), _errno(error)
85  {
86  std::stringstream ss;
87  ss << error << ": " << ::strerror(error);
88  __what = ss.str();
89  };
90 
91  virtual ~socket_raw_error() throw()
92  {};
93 
94  virtual const char* what() const throw()
95  {
96  return __what.c_str();
97  }
98 
99  int error() const { return _errno; }
100 
101  private:
102  int _errno;
103  std::string __what;
104  };
105 
106  void initialize_socket();
107 
112  class basesocket {
113  public:
116 
117  virtual ~basesocket() = 0;
118 
124  virtual void up() throw (socket_exception) = 0;
125 
131  virtual void down() throw (socket_exception) = 0;
132 
137  virtual int fd() const throw (socket_exception);
138 
145  virtual int release() throw (socket_exception);
146 
150  void close() throw (socket_exception);
151  void shutdown(int how) throw (socket_exception);
152 
156  bool ready() const;
157 
162  sa_family_t get_family() const throw (socket_exception);
163  static sa_family_t get_family(int fd) throw (socket_exception);
164 
168  static bool hasSupport(const sa_family_t family, const int type = SOCK_DGRAM, const int protocol = 0) throw ();
169 
170  protected:
175  enum socketstate {
180  };
181 
187  basesocket();
188  basesocket(int fd);
189 
193  void check_socket_error(const int err) const throw (socket_exception);
194  void check_bind_error(const int err, const std::string &msg = "") const throw (socket_exception);
195 
196  void set_blocking_mode(bool val, int fd = -1) const throw (socket_exception);
197  void set_keepalive(bool val, int fd = -1) const throw (socket_exception);
198  void set_linger(bool val, int l = 1, int fd = -1) const throw (socket_exception);
199  void set_reuseaddr(bool val, int fd = -1) const throw (socket_exception);
200  void set_nodelay(bool val, int fd = -1) const throw (socket_exception);
201 
202  void init_socket(const vaddress &addr, int type, int protocol) throw (socket_exception);
203  void init_socket(int domain, int type, int protocol) throw (socket_exception);
204 
205  void bind(int fd, struct sockaddr *addr, socklen_t len) throw (socket_exception);
206 
207  // contains the current socket state
209 
210  // contains the file descriptor if one is available
211  int _fd;
212 
213  // stores the socket family
214  sa_family_t _family;
215  };
216 
221  class clientsocket : public basesocket {
222  public:
224  NO_DELAY = 0,
225  BLOCKING = 1
226  };
227 
228  virtual ~clientsocket() = 0;
229  virtual void up() throw (socket_exception);
230  virtual void down() throw (socket_exception);
231 
232  ssize_t send(const char *data, size_t len, int flags = 0) throw (socket_exception);
233  ssize_t recv(char *data, size_t len, int flags = 0) throw (socket_exception);
234 
235  void set(CLIENT_OPTION opt, bool val) throw (socket_exception);
236 
237  protected:
238  clientsocket();
239  clientsocket(int fd);
240  };
241 
242  class serversocket : public basesocket {
243  public:
245  BLOCKING = 0
246  };
247 
248  virtual ~serversocket() = 0;
249  virtual void up() throw (socket_exception) = 0;
250  virtual void down() throw (socket_exception) = 0;
251 
252  void listen(int connections) throw (socket_exception);
253  virtual clientsocket* accept(ibrcommon::vaddress &addr) throw (socket_exception) = 0;
254 
255  void set(SERVER_OPTION opt, bool val);
256 
257  protected:
258  serversocket();
259  serversocket(int fd);
260 
261  int _accept_fd(ibrcommon::vaddress &addr) throw (socket_exception);
262  };
263 
264  class datagramsocket : public basesocket {
265  public:
266  virtual ~datagramsocket() = 0;
267  virtual void up() throw (socket_exception) = 0;
268  virtual void down() throw (socket_exception) = 0;
269 
270  virtual ssize_t recvfrom(char *buf, size_t buflen, int flags, ibrcommon::vaddress &addr) throw (socket_exception);
271  virtual void sendto(const char *buf, size_t buflen, int flags, const ibrcommon::vaddress &addr) throw (socket_exception);
272 
273  protected:
274  datagramsocket();
275  datagramsocket(int fd);
276  };
277 
281  class filesocket : public clientsocket {
282  public:
283  filesocket(int fd);
284  filesocket(const File &file);
285  virtual ~filesocket();
286  virtual void up() throw (socket_exception);
287  virtual void down() throw (socket_exception);
288 
289  private:
290  const File _filename;
291  };
292 
298  public:
299  fileserversocket(const File &file, int listen = 0);
300  virtual ~fileserversocket();
301  virtual void up() throw (socket_exception);
302  virtual void down() throw (socket_exception);
303 
304  virtual clientsocket* accept(ibrcommon::vaddress &addr) throw (socket_exception);
305 
306  private:
307  void bind(const File &file) throw (socket_exception);
308 
309  private:
310  const File _filename;
311  const int _listen;
312  };
313 
317  class tcpsocket : public clientsocket {
318  public:
319  tcpsocket(int fd);
320  tcpsocket(const vaddress &destination, const timeval *timeout = NULL);
321  virtual ~tcpsocket();
322  virtual void up() throw (socket_exception);
323  virtual void down() throw (socket_exception);
324 
325  private:
326  const vaddress _address;
327  timeval _timeout;
328  };
329 
335  class tcpserversocket : public serversocket {
336  public:
337  tcpserversocket(const int port, int listen = 0);
338  tcpserversocket(const vaddress &address, int listen = 0);
339  virtual ~tcpserversocket();
340  virtual void up() throw (socket_exception);
341  virtual void down() throw (socket_exception);
342 
343  const vaddress& get_address() const;
344 
345  virtual clientsocket* accept(ibrcommon::vaddress &addr) throw (socket_exception);
346 
347  protected:
348  void bind(const vaddress &addr) throw (socket_exception);
349 
350  private:
351  const vaddress _address;
352  const int _listen;
353  };
354 
359  class udpsocket : public datagramsocket {
360  public:
361  udpsocket();
362  udpsocket(const vaddress &address);
363  virtual ~udpsocket();
364  virtual void up() throw (socket_exception);
365  virtual void down() throw (socket_exception);
366 
367  const vaddress& get_address() const;
368 
369  protected:
370  void bind(const vaddress &addr) throw (socket_exception);
371 
373  };
374 
375  class multicastsocket : public udpsocket {
376  public:
377  multicastsocket(const vaddress &address);
378  virtual ~multicastsocket();
379  virtual void up() throw (socket_exception);
380  virtual void down() throw (socket_exception);
381 
382  void join(const vaddress &group, const vinterface &iface) throw (socket_exception);
383  void leave(const vaddress &group, const vinterface &iface) throw (socket_exception);
384 
385  private:
386  void mcast_op(int optname, const vaddress &group, const vinterface &iface) throw (socket_exception);
387  };
388 }
389 
390 #endif /* IBRCOMMON_SOCKET_H_ */