客户端 - 服务器多线程程序通过命名管道实现

时间:2010-12-07 23:57:37

标签: c multithreading client-server named-pipes

我在多线程环境中遇到了客户端 - 服务器程序的问题,案例如下:客户端通过由进程服务器创建的管道发送4个字符串,该管道通过命令行传递,如下所示:

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

服务器创建一个管道来监听客户端请求和许多线程,这些线程将提供-t指定的许多请求(它使用getopt函数。)

问题是我不知道,我甚至不能,服务器监听getopt指定的请求数,即只能听到来自单个客户端进程和complet的请求。

这是我的客户端程序代码:

#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 个答案:

答案 0 :(得分:2)

看起来你正在main()内部进行read()调用,而不是在thread函数内部。由于read()调用将被阻塞,因此它们需要在单独的线程中完成,否则(如您所见)您的主线程将阻塞等待单个客户端,并且无法并行地为其他客户端提供服务。 / p>