Программа многопоточности клиент-сервер, реализованная через именованные каналы - PullRequest
1 голос
/ 08 декабря 2010

У меня проблема с клиент-серверной программой в многопоточной среде, случай таков: клиент отправляет 4 строки через канал, созданный сервером процессов, который передается через командную строку следующим образом:

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

Сервер создает канал для прослушивания клиентских запросов и ряд потоков, которые будут обслуживать столько запросов, сколько может быть указано с помощью -t (он использует функцию getopt.)

проблема в том, что я не знаю и даже не смог, сервер прослушивает количество запросов, указанное getopt, то есть может только услышать петицию от одного клиентского процесса и завершиться.

Вот мой код клиентской программы:

#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 );
}

Вот мой код на сервер:

    #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;
}

Извините, если вопрос довольно глупый, я новичок в этом языке ... спасибо всем за вашу помощь и извините за мой английский, исправьте код, мне нужен кто-то, кто действительно поможет мне в этом. спасибо всем

1 Ответ

2 голосов
/ 08 декабря 2010

Похоже, что вы выполняете вызовы read () внутри main (), а не внутри функции потока.Поскольку вызовы read () будут блокироваться, они должны выполняться в отдельных потоках, иначе (как вы видели) ваш основной поток заблокирует ожидание одного клиента и не сможет параллельно обслуживать других клиентов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...