0

I have a server made of a master and some slaves (one for the example)

I would like the master to distribute clients on connection.

//Initialisation
struct sockaddr_in clientaddr;
socklen_t clientlen;
clientlen = (socklen_t)sizeof(clientaddr);
int listenfd = Open_listenfd(PORT);

//Children instanciation here
int pipe_in = 0;
for (int i = 0; i < NPROC; i++)
{
    int p[2];
    pipe(p);
    children[i].id=Fork();
    if(children[i].id == 0){
        close (p[1]);
        pipe_in=p[0];
        goto CHILDREN;
    }
    else{
        close (p[0]);
        children[i].pipe_to = p[1];
    }
}


//Master Loop
int curchild = 0;
while (1) {
    int connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen);
    write(children[curchild].pipe_to, &connfd, sizeof(connfd));
    printf("Sent to slave %d\n",connfd);
    curchild = Next(curchild);
}

return 0;


//Slave Process
CHILDREN :
while (1) {
    int connfd;
    read(pipe_in, &connfd, sizeof(connfd));
    printf("Receveid from master %d\n",connfd);
    Rio_writen(connfd, "Test\n", 5);
    Close(connfd);
}

Here the descriptor sent and receiveid are similar, but the Rio_writen returns an error : Bad file descriptor

Foxhunt
  • 764
  • 1
  • 9
  • 23

1 Answers1

1

File and socket descriptors are passed to child processes only if they're opened before creating the child processes.

For instance:

  • Parent: accepts new TCP request (thus receiving a new connfd)
  • Parent: forks, creating a new child
  • Parent: passes the connfd to the new child
  • Child: handles the socket connection

Further info: How can I pass a socket from parent to child processes - StackOverflow

Luca Polito
  • 2,387
  • 14
  • 20
  • I have set my socket instanciation before the children creation. I posted my whole code. But can i accept in child ? I need to do a Round-Robin with processes so i need to have all my children always up – Foxhunt Mar 31 '20 at 19:51
  • Yes, you can open the socket in the parent process, create some child processes, and then send the socket descriptor to your children so that they can accept incoming requests. The round-robin logic is already implemented by Linux, you just need your child processes to call `accept()`. – Luca Polito Mar 31 '20 at 22:37