通过命名管道实现的客户端-服务器多线程程序
我在多线程环境中的客户端-服务器程序遇到问题,情况如下:客户端通过进程服务器创建的管道发送 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看起来您是在 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.