sockets - How to read() from clients and a FIFO using select() in C -


i read() clients connected server, , @ same time, let select() aware of data coming fifo. right now, when data written fifo, selects writes data clients keeps returning if "ready-to-read". next read set -1 , errno == eagain. until reaches fdmax. works okay though.

but, why keep getting eagain? , there better way handle this? or proper way?

note: i'm passing o_rdwr|o_nonblock can keep read()ing data sent clients , not fifo.

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #include <fcntl.h> #include <errno.h>  #define port "9034" int main(void) {     fd_set master, read_fds;     int fdmax, listener, newfd, sbytes, yes=1, i, j, rv;      struct sockaddr_storage remoteaddr; // client address     socklen_t addrlen;     char buf[256] = {0}, remoteip[inet6_addrstrlen];     struct addrinfo hints, *ai;      fd_zero(&master);     fd_zero(&read_fds);     int fifo;     if ((mkfifo("/tmp/fifo", 0666)) < 0)         perror(strerror(errno));     if ((fifo = open("/tmp/fifo", o_rdwr|o_nonblock)) < 0)           perror(strerror(errno));      // socket , bind     memset(&hints, 0, sizeof hints);     hints.ai_family = af_unspec;     hints.ai_socktype = sock_stream;     hints.ai_flags = ai_passive;     rv = getaddrinfo(null, port, &hints, &ai);     listener = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);     setsockopt(listener, sol_socket, so_reuseaddr, &yes, sizeof(int));     bind(listener, ai->ai_addr, ai->ai_addrlen);     freeaddrinfo(ai);     listen(listener, 10);      fd_set (fifo, &master);     fd_set(listener, &master);     fdmax = listener;     (;;) {         read_fds = master;         if (select(fdmax + 1, &read_fds, null, null, null) == -1) exit(4);          (i = 0; <= fdmax; i++) {             if (fd_isset(i, &read_fds)) {                 if (i == listener) {                     addrlen = sizeof remoteaddr;                     newfd = accept(listener, (struct sockaddr * ) & remoteaddr, & addrlen);                     fd_set(newfd, & master);                     if (newfd > fdmax)                         fdmax = newfd;                 } else if (i != fifo) {                     recv(i, buf, sizeof buf, 0);                  }                }             if (fd_isset(fifo, &read_fds)) {                 sbytes = read (fifo, buf, sizeof (buf));                 if (sbytes == -1 && errno == eagain)                     continue;                 for(j = 0; j <= fdmax; j++) {                     // send everyone!                     if (fd_isset(j, &master)) {                         if (j != listener && j != && j != fifo) {                             if (send(j, buf, sbytes, 0) == -1) {                                 perror("send");                             }                            }                        }                    }                }            }        }        return 0; } 

for (i = 0; <= fdmax; i++) { 

here iterating read_fds.

if (fd_isset(fifo, &read_fds)) { 

here testing whether fifo readable. every time around loop. first time, read something, , send it; next time around loop, nothing has happened fifo, condition above still holds, read again , eagain.

this if block should outside , below loop.


Comments

Popular posts from this blog

Ansible - ERROR! the field 'hosts' is required but was not set -

customize file_field button ruby on rails -

SoapUI on windows 10 - high DPI/4K scaling issue -