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
Post a Comment