The task is this: there is a parent process - a server, and several client-children. It is necessary that the client sends the message to the server through the pipes, and the server sends it to the other clients.
#include <stdio.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <errno.h> #include <sys/types.h> struct client{ int fd[2]; pid_t pid; }; int main(){ fd_set read_set; struct client clients[2]; struct client servers[2]; struct timeval tv; tv.tv_sec = 2; tv.tv_usec = 0; int i = 0; int j = 0; int k = 0; int r = 0; int serverbytes; int clientbytes; char serverbuffer[80]; char clientbuffer[80]; char message[80]; for(r;r<2;r++) { if(pipe(clients[r].fd) < 0) printf("pipe %i error \n", r); else printf("client pipe %i created \n", r); } r = 0; for(r;r<2;r++) { if(pipe(servers[r].fd) < 0) printf("pipe %i error \n", r); else printf("server pipe %i created \n", r); } clients[0].pid = fork(); if(clients[0].pid != 0) { clients[1].pid = fork(); if(clients[1].pid != 0){ printf("server works. pid=%i \n", getpid()); while(1){ int maxfd = clients[1].fd[0]; FD_ZERO(&read_set); FD_SET(clients[0].fd[0], &read_set); FD_SET(clients[1].fd[0], &read_set); int serverSelect = select(maxfd+1, &read_set, NULL, NULL, &tv); if(serverSelect != -1){ for(k;k<2;k++) { if(FD_ISSET(clients[k].fd[0], &read_set)){ serverbytes = read(clients[k].fd[0], serverbuffer, sizeof(serverbuffer)); printf("server receive: %s from client ID=%d \n", serverbuffer, k); for(i;i<2;i++){ if(i!=k){ close(servers[k].fd[0]); write(servers[k].fd[1], serverbuffer, sizeof(serverbuffer)); } } } } } else if(serverSelect == 0) printf("select timeout \n"); else perror("err"); sleep(5); } } else { sprintf(message,"child %d", 1); printf("client %i works. pid=%i \n", 1, getpid()); //close(servers[1].fd[1]); //open(servers[1].fd[0]); //if(read(servers[1].fd[0], clientbuffer, sizeof(clientbuffer)) == -1){ //printf("client %i read error \n",1); //} //else //printf("client %i receive %s \n",1,clientbuffer); //close(clients[1].fd[0]); while(1){ write(clients[1].fd[1], message, (strlen(message)+1)); printf("client %i send: %s \n", 1, message); sleep(3); } exit(0); } } else { sprintf(message,"child %d", 0); printf("client %i works. pid=%i \n", 0, getpid()); //close(servers[0].fd[1]); //open(servers[0].fd[0]); //if(read(servers[0].fd[0], clientbuffer, sizeof(clientbuffer)) == -1){ //printf("client %i read error \n",1); //} //else //printf("client %i receive %s \n",1,clientbuffer); //close(clients[0].fd[0]); while(1){ write(clients[0].fd[1], message, (strlen(message)+1)); printf("client %i send: %s \n", 0, message); sleep(3); } exit(0); } return 0; }
I make for each client two paypas - for sending to the server and for receiving from the server. The problem is that the server does not execute select c errno = 2 (no such file or directory). Why such a mistake? Thank you in advance.
UPD: after changes from @avp and wrapping processes into infinite loops (the program itself is some kind of chat chatting) the output of the program:
client pipe 0 created client pipe 1 created server pipe 0 created server pipe 1 created client 0 works. pid=32663 client 1 works. pid=32664 client 0 send: child 0 client 1 send: child 1 server works. pid=32662 server receive: child 0 from client ID=0 server receive: child 1 from client ID=1 client 0 send: child 0 client 1 send: child 1 client 0 send: child 0 client 1 send: child 1 client 1 send: child 1 client 0 send: child 0 client 1 send: child 1 client 0 send: child 0 client 1 send: child 1 client 0 send: child 0
That is, the server receives once messages from the client, and after that they spin. Why only once?
Child processes should also receive redirected messages from the server, everything is written for this, but I had to be commented out, because otherwise even the basis does not work ... I understand that the question is most likely stupid, but I am only learning to write under the rules.