franvergara66
franvergara66

Reputation: 10784

Client-server multithreading program implemented through named pipes

I've a problem with a client-server program in a multithreading environment, the case is as follows: the client sends 4 Strings, through a pipe created by a process server that is passed through the command line as follows way:

  @./server -p <named_pipe> -t <threads_numbers>
e.g @./server -p Pipea -t 15

The server creates a pipe to listen to client requests and a number of threads that will serve as many requests as may be specified by-t (it uses the getopt function.)

the problem is I don't know and I couldn't even, the server listen to the number of requests specified by getopt, ie only can hear a petition from a single client process and complet.

Here's my code to client program:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

int main( int argc, char **argv )
{
int f, g,pipe_id;
char pipe [250];
FILE *entrada;
char temp [500];
char comando [500];
char maquina [500];
char dir_ip [500];
//char *comando, *maquina, *dir_ip;

 printf("@>");
    scanf ("%s %s %s", comando, maquina, dir_ip);


 //take the pid of p. client to create the pipe
 sprintf( pipe, "%d", getpid() );

 // Pipe created by the pipe client process will name the client process PID.
 if((mkfifo(pipe,0666))==-1)
 {
 perror("error creando tuberia");
 exit(1);
 }


 //This file contains the last name of the server process for the pipe
 entrada = fopen("tubo.txt", "r");
 fscanf (entrada, "%s\n",temp);


 if((f=open(temp ,O_WRONLY | O_CREAT | O_TRUNC, 0644))==-1)
 {
 perror("error abriendo tuberia");
 exit(1);
 }

 write (f, pipe, 300);
 write(f,comando,300);
 write(f,maquina,300);
 write(f,dir_ip,300);

 close (f);

 wait(1);

 char * a =(char *) malloc (sizeof(char )*5);//flAg

 if((g=open(pipe,O_RDONLY))==-1)
 {
 perror("error creating pipe");
 exit(1);
 }


read(g,a,300); //read the feedback form server 

printf ("feedback server: %s\n", a);

return ( 0 );
}

Here's my code to the server:

    #include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

#define NUM_THREADS 10

struct thread_data{
 char *pipe_id;
 char *comando;
 char *maquina;
 char *ip;
};

struct thread_data thread_data_array[NUM_THREADS];

//function thread
void *solicitud(void *threadarg) {

 int j, g, cont;
 char *pipe, *com, *maq, *dir_ip;
 char *maquina, *direccion;
 char flag [15]= "OK";
 struct thread_data *my_data;

 my_data = (struct thread_data *) threadarg;
 pipe = my_data->pipe_id;
 com = my_data->comando;
 maq = my_data->maquina;
 dir_ip = my_data->ip;
 printf("pipe id %s: command:%s machine:%s ip_address:%s\n", pipe, com, maq, dir_ip);

 j= atoi (pipe);
 if((j=open(pipe,O_WRONLY))==-1)
  {
  perror("error opning pipe");
  exit(1);
  }
  write (j, flag, 300);
  close(j);

pthread_exit(NULL);

}


int main (int argc, char *argv []){

FILE *entrada, *salida;

char *aux;
char busq [200];
char *PipeName = NULL; //nombre del pipe
int index; //non-option
int NumberThreads = 0;
int c; //getoopt
int f;
int rc, t=0;
pthread_t threads[NUM_THREADS];
char * a =(char *) malloc (sizeof(char )*300);
char * b =(char *) malloc (sizeof(char )*300);
char * d =(char *) malloc (sizeof(char )*300);
char * pid_ =(char *) malloc (sizeof(char )*300);

opterr = 0;

 while ((c = getopt (argc, argv, "p:t:")) != -1)

 switch (c)
 {
  case 't':
   NumberThreads = atoi(optarg);

   break;
  case 'p':
   PipeName = optarg;

          break;
  case '?':
   if ((optopt == 'p')||(optopt=='t'))
   fprintf (stderr, "Opcion -%c Needs Argument.\n", optopt);
   else if (isprint (optopt))
   fprintf (stderr, "Unknow Option `-%c'.\n", optopt);
   else
   fprintf (stderr,"unknow answer...`\\x%x'.\n",optopt);


   return 1;

  default:
   abort ();
 }

        printf ("Slaves Threads= %d, PipeName = %s\n",NumberThreads, PipeName);

for (index = optind; index < argc; index++)
printf ("Non-option argument %s\n", argv[index]);

//array of threads
pthread_t mythreads [NumberThreads];


 if((mkfifo(PipeName,0666))==-1)
 {
 perror("error creating pipe");
 exit(1);
 }


 salida = fopen("tubo.txt", "w");
 fprintf(salida,"%s\n", PipeName);
 fclose (salida);

 if((f=open(PipeName,O_RDONLY | O_CREAT | O_TRUNC, 0644))==-1)
 {
  perror("error creating pipe");
  exit(1);
 }


for (;;){

 read(f, pid_, 300); /
 read(f,a,300);
 read(f,b,300);
 read (f,d,300);
 close(f);

in the commented code try to make the server listen to as many requests as may be specified by the command line didnt work


  thread_data_array[t].pipe_id = pid_;
  thread_data_array[t].comando = a;
  thread_data_array[t].maquina = b;
  thread_data_array[t].ip = d;


  rc = pthread_create(&threads[t], NULL, solicitud,
  (void *) &thread_data_array[t]);

  if (rc)
  {
   printf("ERR; pthread_create() ret = %d\n", rc);
   exit(-1);
  }
 t++;

 if (t==NumberThread){
     break;
     }

}//end loop

pthread_exit(NULL);


return 0;
}

Sorry if the question is rather silly, I'm new to this language .. thank you all for your help and excuse my English, fix some code, I need someone to really help me with this. thanks to all

Upvotes: 1

Views: 1772

Answers (1)

Jeremy Friesner
Jeremy Friesner

Reputation: 73091

It looks like you are doing the read() calls inside of main(), instead of inside the thread function. Since the read() calls will block, they need to be done in separate threads, otherwise (as you have seen) your main thread will block waiting for a single client and won't be able to service the other clients in parallel.

Upvotes: 2

Related Questions