Ciao a tutti,
devo fare questo esercizio:
"Creare un server che utilizzi le socket AF_UNIX e più thread concorrenti per gestire un numero di client. Ogni client all'avvio decide quanti messaggi inviare (casualmente). Tutti i messaggi inviati contengono il PID del processo client che li invia. Il srever stampa tutti i messaggi ricevuti sullo standard output.
Il server e' realizzato usando più thread. Un thread dispatcher che accetta le connessioni dai vari client e un thread worker per ogni client. Il thread worker viene attivato appena la connessione si stabilisce e si occupa di leggere i messaggi del client e stamparli sullo stdout. Quando il client termina l'invio (EOF) il thread worker corrispondente termina e libera la memoria occupata."
Il mio problema è che il codice si compila e termina correttamente però l'output non è quello desiderato. È come se ogni processo scriva sulla socket il suo pid un numero indefinito di volte. Posto il codice e alcuni output del programma.
QUESTO È IL CODICE
codice:#include <stdio.h> #include <time.h> #include <stdlib.h> #include <errno.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #include <sys/socket.h> #include <sys/un.h> #include <string.h> #include <pthread.h> #define N_MSG_MAX 10 #define N_CLIENT 5 #define SOCK_NAME "./socket" #define UNIX_PATH_MAX 108 #define N_MAX 50 typedef struct l { int FD; pthread_t PID; struct l* next; } list; /*Prototipi delle funzioni*/ void *thread_disp (void * arg) ; void *thread_worker (void *arg); void client (); int main () { pthread_t TID; /*TID del thread_disp*/ pid_t clients_arr [N_CLIENT]; /*Array con gli indici dei processi client*/ int i=0, err=0; /*Creo thread_disp*/ if((err=pthread_create (&TID, NULL, &thread_disp, NULL))==-1) { errno=err; perror ("Creating t_disp"); exit (errno); } /*Creo i processi client e gli faccio eseguire la funzione client*/ for (i=0;i<N_CLIENT;i++) { /*printf ("CREO CLI***\n");*/ if ((clients_arr[i]=fork())==-1) { perror ("Creating process"); exit (errno); } if (clients_arr[i]==0) { printf ("SONO NEL CLIENT\n"); client (); return 0; } } /*Attendo il completamento del thread_disp e dei processi client*/ pthread_join (TID, NULL); for (i=0;i<N_CLIENT;i++) waitpid (clients_arr[i], NULL, 0); return 0; } /*@@@@__FUNZIONE PER THREAD_DISP__@@@@*/ /*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ void *thread_disp (void *arg) { list *L=NULL, *app=NULL; /*Lista di tutti i FD dei socket e dei PID dei relativi thread*/ struct sockaddr_un sa; /*Struttura per l'indirizzo della socket*/ int fd_skt=0; /*File descriptor della socket*/ int i=0; /*Inizializzo la struttura che contiene l'indirizzo * del socket per accettare le connessioni*/ strncpy (sa.sun_path, SOCK_NAME, UNIX_PATH_MAX); sa.sun_family= AF_UNIX; /*Creo la socket, le assegno un nome e mi metto in ascolto per nuove connessioni*/ if ((fd_skt= socket (AF_UNIX, SOCK_STREAM, 0))==-1) { perror ("Creating socket"); exit (errno); } if ((bind (fd_skt, (struct sockaddr *) &sa, sizeof (sa)))==-1) { perror ("Binding socket"); exit (errno); } if ((listen (fd_skt, SOMAXCONN))==-1) { perror ("Listening for fd_skt"); exit (errno); } /*Per ogni client creo un nuovo elemento della lista che contiene il file descriptor della socket per quel processo e il pid del thread che creo per gestire quella connessione.*/ for (i=0;i<N_CLIENT;i++) { app=L; L= (list *) malloc (sizeof(list)); L->next=app; if ((L->FD= accept (fd_skt, NULL, 0))==-1) { perror ("Accepting connection"); exit (errno); } if ((L->PID=pthread_create (&(L->PID), NULL, &thread_worker, (void *) L->FD))!=0) { errno=L->PID; perror ("Creating t_worker"); exit (errno); } } /*Attendo la terminazione di tutti i thread_worker*/ app=L; while (app!=NULL) { pthread_join (app->PID, NULL); close (app->FD); app=app->next; } /*Chiudo il file descriptor della socket e la rimuovo dal file system*/ close (fd_skt); remove (SOCK_NAME); return (void *) 0; } /*Funzione che esegue ogni client*/ void client () { int FD=0, n=5; struct sockaddr_un sa; char buffer [N_MAX]; /*srand (time(NULL)); n=rand () % N_MSG_MAX +1;*/ sprintf (buffer, "%d", getpid()); /*Inizializzo la struttura che contiene l'indirizzo della socket * per accettare le connessioni e creo la socket per connettermi al server*/ strncpy (sa.sun_path, SOCK_NAME, UNIX_PATH_MAX); sa.sun_family= AF_UNIX; FD= socket (AF_UNIX, SOCK_STREAM, 0); /*Se la connessione va male perché la macchina non è nel network, * aspetto un secondo e riprovo la connessione*/ while ((connect(FD, (struct sockaddr *) &sa, sizeof (sa)))==-1) { if (errno==ENOENT) sleep (1); else exit (errno); } /*Scrivo per n volte il pid del processo sulla socket*/ while (n) { printf ("%s scrive sulla socket\n", buffer); if ((write (FD, buffer, N_MAX))==-1) { perror ("Writing on socket"); exit (errno); } n--; } close (FD); return ; } /*Funzione che esegue ogni thread worker di un processo*/ void * thread_worker (void *arg) { int FD= (int) arg; char buffer [N_MAX]; while ((read (FD, buffer, N_MAX))!=-1) { printf ("PID-->\t%s\n", buffer); } close (FD); return (void *) 0; }

Rispondi quotando