Fawkes API  Fawkes Development Version
socket.cpp
1 
2 /***************************************************************************
3  * socket.h - Fawkes socket base class
4  *
5  * Created: Thu Nov 09 14:30:56 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 #include <netcomm/socket/socket.h>
25 
26 #include <core/exceptions/system.h>
27 #include <utils/time/time.h>
28 
29 #ifndef _GNU_SOURCE
30 #define _GNU_SOURCE
31 #endif
32 
33 #include <errno.h>
34 #include <sys/types.h>
35 #include <sys/socket.h>
36 #include <netdb.h>
37 #include <unistd.h>
38 #include <fcntl.h>
39 #include <string.h>
40 #include <stdlib.h>
41 // include <linux/in.h>
42 #include <netinet/in.h>
43 #include <netinet/in_systm.h>
44 #include <netinet/ip.h>
45 #include <poll.h>
46 
47 #include <cstdio>
48 
49 // Until this is integrated from linux/in.h to netinet/in.h
50 #ifdef __linux__
51 # ifndef IP_MTU
52 # define IP_MTU 14
53 # endif
54 #endif // __linux__
55 #ifdef __FreeBSD__
56 # include <net/if.h>
57 # include <sys/ioctl.h>
58 #endif
59 
60 namespace fawkes {
61 
62 /** @class SocketException netcomm/socket/socket.h
63  * Socket exception.
64  * Thrown if an exception occurs in a socket. If the error was caused by
65  * a system call that sets errno this is given to the exception.
66  * @ingroup NetComm
67  */
68 
69 /** Constructor.
70  * @param msg reason that caused the exception.
71  */
73  : Exception("%s", msg)
74 {
75 }
76 
77 
78 /** Constructor.
79  * @param msg reason of the exception
80  * @param _errno error number (errno returned by a syscall)
81  */
83  : Exception(_errno, "%s", msg)
84 {
85 }
86 
87 
88 /** @class Socket netcomm/socket/socket.h
89  * Socket base class.
90  * This is the base class for all sockets. You cannot use it directly
91  * but you have to use one of the derivatives like StreamSocket or
92  * DatagramSocket.
93  * @ingroup NetComm
94  * @author Tim Niemueller
95  */
96 
97 /** @var Socket::sock_fd
98  * Socket file descriptor.
99  */
100 /** @var Socket::timeout
101  * Timeout in seconds for various operations. If the timeout is non-zero
102  * the socket is initialized non-blocking and operations are aborted after
103  * timeout seconds have passed.
104  */
105 /** @var Socket::client_addr
106  * Client address, set if connected.
107  */
108 /** @var Socket::client_addr_len
109  * length in bytes of client address.
110  */
111 
112 
113 /** Data can be read. */
114 const short Socket::POLL_IN = POLLIN;
115 
116 /** Writing will not block. */
117 const short Socket::POLL_OUT = POLLOUT;
118 
119 /** There is urgent data to read (e.g., out-of-band data on TCP socket;
120  * pseudo-terminal master in packet mode has seen state change in slave).
121  */
122 const short Socket::POLL_PRI = POLLPRI;
123 
124 /** Stream socket peer closed connection, or shut down writing half of
125  * connection. The _GNU_SOURCE feature test macro must be defined
126  * in order to obtain this definition (since Linux 2.6.17).
127  */
128 #ifdef POLLRDHUP
129 const short Socket::POLL_RDHUP = POLLRDHUP;
130 #else
131 const short Socket::POLL_RDHUP = 0;
132 #endif
133 
134 /** Error condition. */
135 const short Socket::POLL_ERR = POLLERR;
136 
137 /** Hang up. */
138 const short Socket::POLL_HUP = POLLHUP;
139 
140 /** Invalid request. */
141 const short Socket::POLL_NVAL = POLLNVAL;
142 
143 
144 /** Constructor similar to syscall.
145  * This creates a new socket. This is a plain pass-through constructor
146  * to the socket() syscall. In most cases this should only be used by
147  * a derivate.
148  * @param domain communication domain, selects the protocol
149  * @param type type of the sockets which specifies communication semantics
150  * @param protocol protocol to use, most types support only one and protocol
151  * should be 0
152  * @param timeout See Socket::timeout.
153  * @exception SocketException thrown if socket cannot be opened, check errno for cause
154  */
155 Socket::Socket(int domain, int type, int protocol, float timeout)
156 {
157  this->timeout = timeout;
158  if ( (sock_fd = socket(domain, type, protocol)) == -1 ) {
159  throw SocketException("Could not open socket", errno);
160  }
161 
162  if (timeout > 0.f) {
163  // set to non-blocking
164  if ( fcntl(sock_fd, F_SETFL, O_NONBLOCK) == -1 ) {
165  throw SocketException("Could not set socket to non-blocking", errno);
166  }
167  }
168 
169  client_addr = NULL;
170  client_addr_len = 0;
171 }
172 
173 
174 /** Constructor.
175  * Plain constructor. The socket will not be opened. This may only be called by
176  * sub-classes and you must ensure that the socket file descriptor is initialized
177  * properly.
178  */
180 {
181  client_addr = NULL;
182  client_addr_len = 0;
183  timeout = 0.f;
184  sock_fd = -1;
185 }
186 
187 
188 /** Copy constructor.
189  * @param socket socket to copy
190  */
192 {
193  if ( socket.client_addr != NULL ) {
194  client_addr = (struct ::sockaddr_in *)malloc(socket.client_addr_len);
195  client_addr_len = socket.client_addr_len;
196  memcpy(client_addr, socket.client_addr, client_addr_len);
197  } else {
198  client_addr = NULL;
199  client_addr_len = 0;
200  }
201  timeout = socket.timeout;
202  sock_fd = socket.sock_fd;
203 }
204 
205 
206 /** Destructor. */
208 {
209  close();
210  if ( client_addr != NULL ) {
211  free(client_addr);
212  client_addr = NULL;
213  }
214 }
215 
216 
217 /** Close socket. */
218 void
220 {
221  if ( sock_fd != -1 ) {
222  ::close(sock_fd);
223  sock_fd = -1;
224  }
225 }
226 
227 
228 /** Connect socket.
229  * If called for a stream socket this will connect to the remote address. If
230  * you call this on a datagram socket you will tune in to a specific sender and
231  * receiver.
232  * @param addr_port struct containing address and port to connect to
233  * @param struct_size size of addr_port struct
234  * @exception SocketException thrown if socket cannot connect, check errno for cause
235  */
236 void
237 Socket::connect(struct sockaddr *addr_port, unsigned int struct_size)
238 {
239  if ( sock_fd == -1 ) throw SocketException("Trying to connect invalid socket");
240 
241  if (timeout == 0.f) {
242  if ( ::connect(sock_fd, addr_port, struct_size) < 0 ) {
243  throw SocketException("Could not connect", errno);
244  }
245  } else {
246  struct timeval start, now;
247  gettimeofday(&start, NULL);
248  do {
249  if ( ::connect(sock_fd, addr_port, struct_size) < 0 ) {
250  if ( (errno != EINPROGRESS) &&
251  (errno != EALREADY) ) {
252  throw SocketException("Could not connect", errno);
253  }
254  }
255  gettimeofday(&now, NULL);
256  } while (time_diff_sec(now, start) < timeout);
257  }
258 }
259 
260 
261 /** Connect socket.
262  * If called for a stream socket this will connect to the remote address. If
263  * you call this on a datagram socket you will tune in to a specific sender and
264  * receiver.
265  * @param hostname hostname or textual represenation of IP address to connect to
266  * @param port port to connect to
267  * @exception SocketException thrown if socket cannot connect, check errno for cause
268  */
269 void
270 Socket::connect(const char *hostname, unsigned short int port)
271 {
272  if ( sock_fd == -1 ) throw SocketException("Trying to connect invalid socket");
273 
274  struct hostent* h;
275  struct ::sockaddr_in host;
276 
277 
278  h = gethostbyname(hostname);
279  if ( ! h ) {
280  throw SocketException("Cannot lookup hostname", h_errno);
281  }
282 
283  memset(&host, 0, sizeof(host));
284  host.sin_family = AF_INET;
285  memcpy((char *)&host.sin_addr.s_addr, h->h_addr, h->h_length);
286  host.sin_port = htons(port);
287 
288  connect((struct sockaddr *)&host, sizeof(host));
289 }
290 
291 
292 /** Bind socket.
293  * Can only be called on stream sockets.
294  * @param port port to bind
295  * @exception SocketException thrown if socket cannot bind, check errno for cause
296  */
297 void
298 Socket::bind(const unsigned short int port)
299 {
300  struct ::sockaddr_in host;
301 
302  host.sin_family = AF_INET;
303  host.sin_addr.s_addr = INADDR_ANY;
304  host.sin_port = htons(port);
305 
306  int reuse = 1;
307  if ( setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1) {
308  throw SocketException("Could not set SO_REUSEADDR", errno);
309  }
310 
311  if (::bind(sock_fd, (struct sockaddr *) &host, sizeof(host)) < 0) {
312  throw SocketException("Could not bind to port", errno);
313  }
314 }
315 
316 
317 /** Bind socket to a specific address.
318  * @param port port to bind
319  * @param hostname hostname or textual IP address of a local interface to bind to.
320  * @exception SocketException thrown if socket cannot bind, check errno for cause
321  */
322 void
323 Socket::bind(const unsigned short int port, const char *hostname)
324 {
325  struct hostent* h;
326  struct ::sockaddr_in host;
327 
328  h = gethostbyname(hostname);
329  if ( ! h ) {
330  throw SocketException("Cannot lookup hostname", h_errno);
331  }
332 
333  memset(&host, 0, sizeof(host));
334  host.sin_family = AF_INET;
335  memcpy(&host.sin_addr.s_addr, h->h_addr, h->h_length);
336  host.sin_port = htons(port);
337 
338  host.sin_family = AF_INET;
339  host.sin_addr.s_addr = INADDR_ANY;
340  host.sin_port = htons(port);
341 
342  if (::bind(sock_fd, (struct sockaddr *) &host, sizeof(host)) < 0) {
343  throw SocketException("Could not bind to port", errno);
344  }
345 }
346 
347 
348 /** Listen on socket.
349  * This waits for new connections on a bound socket. The backlog is the maximum
350  * number of connections waiting for being accepted.
351  * @param backlog maximum number of waiting connections
352  * @exception SocketException thrown if socket cannot listen, check errno for cause
353  * @see bind()
354  * @see accept()
355  */
356 void
357 Socket::listen(int backlog)
358 {
359  if ( ::listen(sock_fd, backlog) ) {
360  throw SocketException("Cannot listen on socket", errno);
361  }
362 }
363 
364 
365 /** Accept connection.
366  * Accepts a connection waiting in the queue.
367  * @return new socket used to communicate with the remote part
368  * @exception SocketException thrown if socket cannot accept, check errno for cause
369  */
370 Socket *
372 {
373  struct ::sockaddr_in tmp_client_addr;
374  unsigned int tmp_client_addr_len = sizeof(struct ::sockaddr_in);
375 
376  int a_sock_fd = -1;
377 
378  a_sock_fd = ::accept(sock_fd, (sockaddr *)&tmp_client_addr, &tmp_client_addr_len);
379  if ( a_sock_fd == -1 ) {
380  if (errno != EWOULDBLOCK) {
381  throw SocketException("Could not accept connection", errno);
382  } else {
383  return NULL;
384  }
385  }
386 
387  // Does not work, evaluated at compile time, thus need clone()
388  //__typeof(this) s = new __typeof(*this);
389  //s->timeout = timeout;
390 
391  Socket *s = clone();
392  s->sock_fd = a_sock_fd;
393 
394  if ( s->client_addr != NULL ) {
395  free(s->client_addr);
396  }
397  struct ::sockaddr_in *tmp_client_addr_alloc = (struct ::sockaddr_in *)malloc(sizeof(struct ::sockaddr_in));
398  memcpy(tmp_client_addr_alloc, &tmp_client_addr, sizeof(struct ::sockaddr_in));
399  s->client_addr = tmp_client_addr_alloc;
400  s->client_addr_len = tmp_client_addr_len;
401 
402  return s;
403 }
404 
405 
406 /** Check if data is available.
407  * Use this to check if data is available on the socket for reading.
408  * @return true, if data can be read, false otherwise
409  */
410 bool
412 {
413  if (sock_fd == -1) return false;
414 
415  fd_set rfds;
416  struct timeval tv;
417  int retval = 1;
418 
419  FD_ZERO(&rfds);
420  FD_SET(sock_fd, &rfds);
421  tv.tv_sec = 0;
422  tv.tv_usec = 0;
423 
424  retval = select(sock_fd + 1, &rfds, NULL, NULL, &tv);
425  if ( retval < 0 ) {
426  perror("select() failed");
427  }
428 
429  return (retval > 0);
430 }
431 
432 
433 /** Wait for some event on socket.
434  * @param timeout timeout in miliseconds to wait. A negative value means to
435  * wait forever until an event occurs, zero means just check, don't wait.
436  * @param what what to wait for, a bitwise OR'ed combination of POLL_IN,
437  * POLL_OUT and POLL_PRI.
438  * @return Returns a flag value. Use bit-wise AND with the POLL_* constants
439  * in this class.
440  * @exception InterruptedException thrown, if poll is interrupted by a signal
441  * @exception SocketException thrown for any other error the poll() syscall can cause,
442  * see Exception::errno() for the cause of the error.
443  * @see Socket::POLL_IN
444  * @see Socket::POLL_OUT
445  * @see Socket::POLL_PRI
446  * @see Socket::POLL_RDHUP
447  * @see Socket::POLL_ERR
448  * @see Socket::POLL_HUP
449  * @see Socket::POLL_NVAL
450  */
451 short
452 Socket::poll(int timeout, short what)
453 {
454  if ( sock_fd == -1 ) {
455  return POLL_ERR;
456  }
457 
458  struct pollfd pfd;
459  pfd.fd = sock_fd;
460  pfd.events = what;
461  pfd.revents = 0;
462  if ( ::poll(&pfd, 1, timeout) == -1 ) {
463  if ( errno == EINTR ) {
464  throw InterruptedException();
465  } else {
466  throw SocketException("poll() failed", errno);
467  }
468  } else {
469  return pfd.revents;
470  }
471 }
472 
473 
474 /** Write to the socket.
475  * Write to the socket. This method can only be used on streams.
476  * @param buf buffer to write
477  * @param count number of bytes to write from buf
478  * @exception SocketException if the data could not be written or if a timeout occured.
479  */
480 void
481 Socket::write(const void *buf, size_t count)
482 {
483  int retval = 0;
484  unsigned int bytes_written = 0;
485  struct timeval start, now;
486 
487  gettimeofday(&start, NULL);
488 
489  do {
490  retval = ::write(sock_fd, (char *)buf + bytes_written, count - bytes_written);
491  if (retval == -1) {
492  if (errno != EAGAIN) {
493  throw SocketException("Could not write data", errno);
494  } else {
495  // just to meet loop condition
496  retval = 0;
497  }
498  } else {
499  bytes_written += retval;
500  // reset timeout
501  gettimeofday(&start, NULL);
502  }
503  gettimeofday(&now, NULL);
504  usleep(0);
505  } while ((bytes_written < count) && (time_diff_sec(now, start) < timeout) );
506 
507  if ( bytes_written < count) {
508  throw SocketException("Write timeout");
509  }
510 }
511 
512 
513 /** Read from socket.
514  * Read from the socket. This method can only be used on streams.
515  * @param buf buffer to write from
516  * @param count length of buffer, number of bytes to write to stream
517  * @param read_all setting this to true causes a call to read() loop until exactly
518  * count bytes have been read, if false it will return after the first successful read
519  * with the number of bytes available then.
520  * @return number of bytes read.
521  * @see write
522  * @exception SocketException thrown for any error during reading
523  */
524 size_t
525 Socket::read(void *buf, size_t count, bool read_all)
526 {
527  int retval = 0;
528  unsigned int bytes_read = 0;
529 
530  if ( timeout > 0 ) {
531  struct timeval start, now;
532 
533  gettimeofday(&start, NULL);
534 
535  if ( read_all ) {
536  do {
537  retval = ::read(sock_fd, (char *)buf + bytes_read, count - bytes_read);
538  if (retval == -1) {
539  if (errno != EAGAIN) {
540  throw SocketException("Could not read data", errno);
541  } else {
542  // just to meet loop condition
543  retval = 0;
544  }
545  } else {
546  bytes_read += retval;
547  // reset timeout
548  gettimeofday(&start, NULL);
549  }
550  gettimeofday(&now, NULL);
551  usleep(0);
552  } while ((bytes_read < count) && (time_diff_sec(now, start) < timeout) );
553  } else {
554  do {
555  retval = ::read(sock_fd, (char *)buf, count);
556  if ( (retval == -1) && (errno != EAGAIN) ) {
557  throw SocketException("Could not read data", errno);
558  } else {
559  bytes_read = retval;
560  }
561  usleep(0);
562  } while (retval < 0);
563  }
564  } else {
565  if ( read_all ) {
566  do {
567  retval = ::read(sock_fd, (char *)buf + bytes_read, count - bytes_read);
568  if (retval == -1) {
569  throw SocketException("Could not read data", errno);
570  } else if (retval == 0) {
571  throw SocketException("Could not read any data");
572  } else {
573  bytes_read += retval;
574  }
575  usleep(0);
576  } while (bytes_read < count);
577  } else {
578  do {
579  retval = ::read(sock_fd, (char *)buf, count);
580  if ( (retval == -1) && (errno != EAGAIN) ) {
581  throw SocketException("Could not read data", errno);
582  } else {
583  bytes_read = retval;
584  }
585  usleep(0);
586  } while (retval < 0);
587  }
588  }
589 
590  if ( read_all && (bytes_read < count)) {
591  throw SocketException("Read timeout");
592  }
593 
594  return bytes_read;
595 }
596 
597 
598 /** Write to the socket.
599  * Write to the socket. This method can be used on streams or on datagram
600  * sockets which have been tuned to a specific receiver by using connect().
601  * For streams usage of write() is recommended as it is the more intuitive
602  * way to deal with a stream.
603  * @param buf buffer to write
604  * @param buf_len length of buffer, number of bytes to write to stream
605  * @see write
606  */
607 void
608 Socket::send(void *buf, size_t buf_len)
609 {
610  try {
611  write(buf, buf_len);
612  } catch (SocketException &e) {
613  throw;
614  }
615 }
616 
617 
618 /** Read from socket.
619  * Read from the socket. This method can only be used on streams. Usage of
620  * read() is recommended.
621  * @param buf buffer to read data into
622  * @param buf_len length of buffer, number of bytes to read from stream
623  * @return number of bytes read
624  * @exception SocketException thrown if an error occurs or the other side
625  * has closed the connection.
626  */
627 size_t
628 Socket::recv(void *buf, size_t buf_len)
629 {
630  ssize_t rv;
631  if ( (rv = ::recv(sock_fd, buf, buf_len, 0)) == -1 ) {
632  throw SocketException("recv() failed", errno);
633  } else if ( rv == 0 ) {
634  throw SocketException("Other side closed the connection");
635  }
636  return rv;
637 }
638 
639 
640 /** Send message.
641  * @param buf buffer with data to send
642  * @param buf_len length of buffer, all data will be send.
643  * @param addr addr to send data to.
644  * @param addr_len length of address
645  */
646 void
647 Socket::send(void *buf, size_t buf_len,
648  const struct sockaddr *addr, socklen_t addr_len)
649 {
650  int retval = 0;
651  unsigned int bytes_written = 0;
652  struct timeval start, now;
653 
654  gettimeofday(&start, NULL);
655 
656  do {
657  retval = ::sendto(sock_fd, (char *)buf + bytes_written, buf_len - bytes_written, 0,
658  addr, addr_len);
659  if (retval == -1) {
660  if (errno != EAGAIN) {
661  throw SocketException("Could not read data", errno);
662  } else {
663  // just to meet loop condition
664  retval = 0;
665  }
666  } else {
667  bytes_written += retval;
668  // reset timeout
669  gettimeofday(&start, NULL);
670  }
671  gettimeofday(&now, NULL);
672  usleep(0);
673  } while ((bytes_written < buf_len) && (time_diff_sec(now, start) < timeout) );
674 
675  if ( bytes_written < buf_len) {
676  throw SocketException("Write timeout");
677  }
678 }
679 
680 
681 /** Receive data.
682  * This will use recvfrom() to read data from the socket and returns the
683  * number of bytes actually read. It will not wait until the requested
684  * number of bytes has been read. Use read() if you need this.
685  * @param buf buffer that read data shall be stored in.
686  * @param buf_len length of buffer and number of bytes to be read
687  * @param addr return parameter, contains address of sender
688  * @param addr_len initially has to contain size of address, on return
689  * contains the actual bytes used.
690  * @return number of bytes received
691  */
692 size_t
693 Socket::recv(void *buf, size_t buf_len,
694  struct sockaddr *addr, socklen_t *addr_len)
695 {
696  ssize_t rv = 0;
697 
698  if ( (rv = ::recvfrom(sock_fd, buf, buf_len, 0, addr, addr_len)) == -1) {
699  throw SocketException("recvfrom() failed", errno);
700  } else if ( rv == 0 ) {
701  throw SocketException("Peer has closed the connection");
702  } else {
703  return rv;
704  }
705 }
706 
707 
708 /** Is socket listening for connections?
709  * @return true if socket is listening for incoming connections, false otherwise
710  */
711 bool
713 {
714  if ( sock_fd == -1 ) return false;
715 
716  int i = 0;
717  unsigned int len = sizeof(i);
718  if ( getsockopt(sock_fd, SOL_SOCKET, SO_ACCEPTCONN, &i, &len) == -1 ) {
719  throw SocketException("Socket::listening(): getsockopt failed", errno);
720  }
721  return ( i == 1 );
722 }
723 
724 
725 /** Maximum Transfer Unit (MTU) of socket.
726  * Note that this can only be retrieved of connected sockets!
727  * @return MTU in bytes
728  */
729 unsigned int
731 {
732  int m = 0;
733 
734  if ( sock_fd == -1 ) throw SocketException("Cannot get MTU of disconnected socket");
735 
736 #ifdef __linux__
737  unsigned int len = sizeof(m);
738  if ( getsockopt(sock_fd, IPPROTO_IP, IP_MTU, &m, &len) == -1 ) {
739  throw SocketException("Socket::mtu(): getsockopt failed", errno);
740  }
741 
742  if ( m < 0 ) {
743  throw SocketException("MTU < 0");
744  }
745 #elif defined __FreeBSD__
746  struct ifreq ifr;
747  if (ioctl(sock_fd, SIOCGIFMTU, &ifr) != -1)
748  m = ifr.ifr_mtu;
749 #endif
750 
751  return m;
752 }
753 
754 } // end namespace fawkes
virtual void connect(const char *hostname, const unsigned short int port)
Connect socket.
Definition: socket.cpp:270
static const short POLL_ERR
Error condition.
Definition: socket.h:73
virtual void close()
Close socket.
Definition: socket.cpp:219
virtual void write(const void *buf, size_t count)
Write to the socket.
Definition: socket.cpp:481
static const short POLL_PRI
There is urgent data to read (e.g., out-of-band data on TCP socket; pseudo-terminal master in packet ...
Definition: socket.h:71
Fawkes library namespace.
SocketException(const char *msg, int _errno)
Constructor.
Definition: socket.cpp:82
virtual size_t recv(void *buf, size_t buf_len)
Read from socket.
Definition: socket.cpp:628
static const short POLL_IN
Data can be read.
Definition: socket.h:69
struct::sockaddr_in * client_addr
Client address, set if connected.
Definition: socket.h:127
Socket()
Constructor.
Definition: socket.cpp:179
int _errno
Error number, should be used if the error was caused by a method that supplies errno.
Definition: exception.h:110
Socket base class.
Definition: socket.h:65
unsigned int client_addr_len
length in bytes of client address.
Definition: socket.h:128
virtual bool available()
Check if data is available.
Definition: socket.cpp:411
virtual Socket * accept()
Accept connection.
Definition: socket.cpp:371
virtual const char * what() const
Get primary string.
Definition: exception.cpp:661
Base class for exceptions in Fawkes.
Definition: exception.h:36
double time_diff_sec(const timeval &a, const timeval &b)
Calculate time difference of two time structs.
Definition: time.h:40
virtual size_t read(void *buf, size_t count, bool read_all=true)
Read from socket.
Definition: socket.cpp:525
The current system call has been interrupted (for instance by a signal).
Definition: system.h:39
virtual void bind(const unsigned short int port)
Bind socket.
Definition: socket.cpp:298
static const short POLL_RDHUP
Stream socket peer closed connection, or shut down writing half of connection.
Definition: socket.h:72
virtual ~Socket()
Destructor.
Definition: socket.cpp:207
virtual bool listening()
Is socket listening for connections?
Definition: socket.cpp:712
virtual unsigned int mtu()
Maximum Transfer Unit (MTU) of socket.
Definition: socket.cpp:730
virtual short poll(int timeout=-1, short what=POLL_IN|POLL_HUP|POLL_PRI|POLL_RDHUP)
Wait for some event on socket.
Definition: socket.cpp:452
int sock_fd
Socket file descriptor.
Definition: socket.h:125
virtual void send(void *buf, size_t buf_len)
Write to the socket.
Definition: socket.cpp:608
static const short POLL_HUP
Hang up.
Definition: socket.h:74
static const short POLL_NVAL
Invalid request.
Definition: socket.h:75
virtual void listen(int backlog=1)
Listen on socket.
Definition: socket.cpp:357
float timeout
Timeout in seconds for various operations.
Definition: socket.h:126
Socket exception.
Definition: socket.h:58
static const short POLL_OUT
Writing will not block.
Definition: socket.h:70