Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C/Linux - Server <-> Terminal communication with named pipes

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:

  • Only 1 server;
  • 1 or more terminals;

Actually my application works like this:

enter image description here

  • The terminal send a command_t structure through a named pipe (in red) to the server. This named pipe is a FIFO and it is shared between all terminals. After sending the command_t strucutre the terminal will try to read the reply from another named pipe (in blue) and it will be blocked until the server writes something in that pipe.
  • The server reads from the named pipe (in red) and processes the commands received (command_t structure) by the first come, first served basis. There are several threads which means several request are processed at the same time.
  • After processing the command the server sends a reply_t structure through another named pipe (in blue).

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: enter image description here

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!

like image 903
Daniel Oliveira Avatar asked Dec 02 '16 02:12

Daniel Oliveira


1 Answers

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.

like image 151
Isaac Gómez Avatar answered Nov 06 '22 06:11

Isaac Gómez