Reputation: 1290
I am working on a project for college where I can ONLY use named pipes (mkfifo()) to establish communication between a server and a terminal (both created by me).
There are:
Actually my application works like this:
The problem:
If I start the server with only one thread this all works fine because the responses (reply_t) are sent in the order of arrival of the commands (command_t)
But if I start the server with more than one thread I can´t guarantee that the responses are sent in the same order of arrival of the commands and this will make me have mixed responses (something like, I will receive on Terminal 1 the result of the execution from the command from Terminal 2 and etc...).
I was thinking about making something like this:
In this solution I would have an output PIPE for each terminal connected to the server instead of one output PIPE shared between all terminals. But how can I implement a variable number of terminals in C? I can´t even detect when a new terminal opens the input PIPE.
Any suggestions? Thanks!
Upvotes: 8
Views: 1739
Reputation: 101
One way to synchronize the server with the terminal is using System V semaphore. The semaphore is taken by a terminal before start "listening" to the channel for "x" minutes. If a message arrive, the terminal process it an send the response back, else, if timeout occurs it just release the semaphore so other terminal can start listening. The problem with this is that you loose the ability to process several message in parallel.
Another approach is as @Moulin said to use an id in (for example the PID returned by fork()
) in your structures command_t
and reply_t
.
Upvotes: 0
Reputation: 156
Daniel,
I implemented a similar server before, you can listen a terminal, and when the terminal finishes the message you can fork the process and send the response back on the child process, whereas in the parent process in a loop you create another listener for the next terminal, as ccarton said:
Something like this:
while (1)
{
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
error("ERROR on accept");
pid = fork();
if (pid < 0)
error("ERROR on fork");
if (pid == 0)
{
close(sockfd);
dostuff(newsockfd);
exit(0);
}
else
close(newsockfd);
} /* end of while */
You can find a complete explanation here: http://www.linuxhowtos.org/C_C++/socket.htm
Under "Enhancements to the server code" Section.
Hope this helps.
Upvotes: 1