2010-12-07 4 views
1

J'ai un problème avec un programme client-serveur dans un environnement multithread, le cas est le suivant: le client envoie 4 chaînes, via un canal créé par un serveur de processus passé à travers la ligne de commande comme suit ainsi:Programme multithreading client-serveur implémenté via des canaux nommés

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

le serveur crée un tuyau pour écouter les demandes des clients et un certain nombre de threads qui servira autant de demandes qui peuvent être spécifiées par t (il utilise la fonction getopt Le problème est je ne sais pas et je ne pouvais même pas, le serveur écoute le nombre de demandes spécifiées par getopt,

c'est-à-dire que seul peut entendre une pétition à partir d'un processus client unique et complète.

Voici mon code programme client:

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

Voici mon code au serveur:

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

Désolé si la question est assez stupide, je suis nouveau dans cette langue .. merci vous tous pour votre aide et excusez mon anglais, corrigez le code, j'ai besoin de quelqu'un pour m'aider vraiment avec ceci. merci à tous

Répondre

2

Il semble que vous faites les appels read() à l'intérieur de main(), plutôt qu'à l'intérieur de la fonction thread. Puisque les appels de read() bloquent, ils doivent être faits dans des threads séparés, sinon (comme vous l'avez vu) votre thread principal bloquera l'attente d'un client unique et ne pourra pas servir les autres clients en parallèle.

+0

est nécessaire lectures dans le principal de sorte qu'il peut être envoyé à la fonction de fil par la structure ou non? – franvergara66

Questions connexes