24 #include <netcomm/socket/socket.h>
26 #include <core/exceptions/system.h>
27 #include <utils/time/time.h>
34 #include <sys/types.h>
35 #include <sys/socket.h>
42 #include <netinet/in.h>
43 #include <netinet/in_systm.h>
44 #include <netinet/ip.h>
57 # include <sys/ioctl.h>
158 if ( (
sock_fd = socket(domain, type, protocol)) == -1 ) {
164 if ( fcntl(
sock_fd, F_SETFL, O_NONBLOCK) == -1 ) {
246 struct timeval start, now;
247 gettimeofday(&start, NULL);
250 if ( (errno != EINPROGRESS) &&
251 (errno != EALREADY) ) {
255 gettimeofday(&now, NULL);
275 struct ::sockaddr_in host;
278 h = gethostbyname(hostname);
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);
288 connect((
struct sockaddr *)&host,
sizeof(host));
300 struct ::sockaddr_in host;
302 host.sin_family = AF_INET;
303 host.sin_addr.s_addr = INADDR_ANY;
304 host.sin_port = htons(port);
307 if ( setsockopt(
sock_fd, SOL_SOCKET, SO_REUSEADDR, &reuse,
sizeof(reuse)) == -1) {
311 if (::
bind(
sock_fd, (
struct sockaddr *) &host,
sizeof(host)) < 0) {
326 struct ::sockaddr_in host;
328 h = gethostbyname(hostname);
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);
338 host.sin_family = AF_INET;
339 host.sin_addr.s_addr = INADDR_ANY;
340 host.sin_port = htons(port);
342 if (::
bind(
sock_fd, (
struct sockaddr *) &host,
sizeof(host)) < 0) {
373 struct ::sockaddr_in tmp_client_addr;
374 unsigned int tmp_client_addr_len =
sizeof(struct ::sockaddr_in);
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) {
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));
413 if (
sock_fd == -1)
return false;
424 retval = select(
sock_fd + 1, &rfds, NULL, NULL, &tv);
426 perror(
"select() failed");
462 if ( ::
poll(&pfd, 1, timeout) == -1 ) {
463 if ( errno == EINTR ) {
484 unsigned int bytes_written = 0;
485 struct timeval start, now;
487 gettimeofday(&start, NULL);
490 retval =
::write(
sock_fd, (
char *)buf + bytes_written, count - bytes_written);
492 if (errno != EAGAIN) {
499 bytes_written += retval;
501 gettimeofday(&start, NULL);
503 gettimeofday(&now, NULL);
507 if ( bytes_written < count) {
528 unsigned int bytes_read = 0;
531 struct timeval start, now;
533 gettimeofday(&start, NULL);
537 retval =
::read(
sock_fd, (
char *)buf + bytes_read, count - bytes_read);
539 if (errno != EAGAIN) {
546 bytes_read += retval;
548 gettimeofday(&start, NULL);
550 gettimeofday(&now, NULL);
556 if ( (retval == -1) && (errno != EAGAIN) ) {
562 }
while (retval < 0);
567 retval =
::read(
sock_fd, (
char *)buf + bytes_read, count - bytes_read);
570 }
else if (retval == 0) {
573 bytes_read += retval;
576 }
while (bytes_read < count);
580 if ( (retval == -1) && (errno != EAGAIN) ) {
586 }
while (retval < 0);
590 if ( read_all && (bytes_read < count)) {
631 if ( (rv = ::
recv(
sock_fd, buf, buf_len, 0)) == -1 ) {
633 }
else if ( rv == 0 ) {
648 const struct sockaddr *addr, socklen_t addr_len)
651 unsigned int bytes_written = 0;
652 struct timeval start, now;
654 gettimeofday(&start, NULL);
657 retval = ::sendto(
sock_fd, (
char *)buf + bytes_written, buf_len - bytes_written, 0,
660 if (errno != EAGAIN) {
667 bytes_written += retval;
669 gettimeofday(&start, NULL);
671 gettimeofday(&now, NULL);
675 if ( bytes_written < buf_len) {
694 struct sockaddr *addr, socklen_t *addr_len)
698 if ( (rv = ::recvfrom(
sock_fd, buf, buf_len, 0, addr, addr_len)) == -1) {
700 }
else if ( rv == 0 ) {
714 if (
sock_fd == -1 )
return false;
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);
737 unsigned int len =
sizeof(m);
738 if ( getsockopt(
sock_fd, IPPROTO_IP, IP_MTU, &m, &len) == -1 ) {
745 #elif defined __FreeBSD__
747 if (ioctl(
sock_fd, SIOCGIFMTU, &ifr) != -1)
virtual void connect(const char *hostname, const unsigned short int port)
Connect socket.
static const short POLL_ERR
Error condition.
virtual void close()
Close socket.
virtual void write(const void *buf, size_t count)
Write to the socket.
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 ...
SocketException(const char *msg, int _errno)
Constructor.
virtual size_t recv(void *buf, size_t buf_len)
Read from socket.
static const short POLL_IN
Data can be read.
struct::sockaddr_in * client_addr
Client address, set if connected.
unsigned int client_addr_len
length in bytes of client address.
virtual bool available()
Check if data is available.
virtual Socket * accept()
Accept connection.
virtual Socket * clone()=0
Clone socket.
Base class for exceptions in Fawkes.
double time_diff_sec(const timeval &a, const timeval &b)
Calculate time difference of two time structs.
virtual size_t read(void *buf, size_t count, bool read_all=true)
Read from socket.
The current system call has been interrupted (for instance by a signal).
virtual void bind(const unsigned short int port)
Bind socket.
static const short POLL_RDHUP
Stream socket peer closed connection, or shut down writing half of connection.
virtual ~Socket()
Destructor.
virtual bool listening()
Is socket listening for connections?
virtual unsigned int mtu()
Maximum Transfer Unit (MTU) of socket.
virtual short poll(int timeout=-1, short what=POLL_IN|POLL_HUP|POLL_PRI|POLL_RDHUP)
Wait for some event on socket.
int sock_fd
Socket file descriptor.
virtual void send(void *buf, size_t buf_len)
Write to the socket.
static const short POLL_HUP
Hang up.
static const short POLL_NVAL
Invalid request.
virtual void listen(int backlog=1)
Listen on socket.
float timeout
Timeout in seconds for various operations.
static const short POLL_OUT
Writing will not block.