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

发布于 2024-10-06 09:31:52 字数 4938 浏览 0 评论 0原文

我在多线程环境中的客户端-服务器程序遇到问题,情况如下:客户端通过进程​​服务器创建的管道发送 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;
}

抱歉,如果问题相当愚蠢,我是这门语言的新手..谢谢大家的帮助,请原谅我的英语,修复一些代码,我需要有人来真的帮助我解决这个问题。感谢大家

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不甘平庸 2024-10-13 09:31:52

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文