I am writing a server which fork()'s off a child process when it accepts a socket connection.
As the child communicates with a client, it must send some of that information back to the parent. I am using a pipe to accomplish this.
The problem is that when I try to do the parent-child IPC, the parent blocks when reading input from the child. Which means that, even though the children are running concurrently, they can only be processed one-at-a-time because they are all waiting for the parent.
My code looks something like this (error-checking removed for brevity):
/* loop: wait for clients to connect */
for(;;) {
pipe(write_to_parent); /* create pipe between parent and child */
pipe(write_to_child); /* create pipe between parent and child */
newsockfd = accept(...);
pid = fork();
if (pid == 0) { /* child process */
close(write_to_parent[0]);
close(write_to_child[1]);
printf("Connected!\n");
while ((rc = recv(newsockfd, ...)) > 0) {
/* process socket request */
/* write stuff to parent that is related to what we recv'd from client */
rc = write(write_to_parent[1], &buf, 1024);
}
printf("Disconnected!\n");
exit(0);
} else { /* parent */
close(write_to_parent[1]);
close(write_to_child[0]);
while (read(write_to_parent[0], &buf, 1024) > 0) {
/* accept data from child process, and do some processing */
}
}
}
So my question is, how do I remedy this? How can I have the parent communicating with a children using pipes in such a way that it is not blocking?
Is this even possible with pipes, or should I used shared memory (with a semaphore, i guess) or message queue instead? (I read this post: http://stackoverflow.com/questions/404604/comparing-unix-linux-ipc but it is really difficult to find examples how these tasks are actually accomplished.)
More details:
I have a test program that does the following: 1. Connect to the server 2. Sleep(5) 3. Disconnect from the server
When I run 2 instances of this program, the server outputs this:
connected!
// pause for 5 seconds
disconnected!
connected!
// pause for 5 seconds
disconnected!
Obviously processing each client one at a time.
When I remove the IPC - when I get rid of the pipe read() and write()'s from both the parent and child, I get this:
connected!
connected!
// pause for 5ish seconds
disconnected!
disconnected!
Which is what I want!
Any thoughts on how I can accomplish this? (or changes I should make in the way I am going about solving this problem?)
(edit: This is part of an assignment for a networking class. We are implementing a P2P protocol that uses a centralized server to manage the peers. We could use any language, and I figured I'd give it a whirl in C .)