Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 13

Discussione: C problema con le fifo

  1. #1
    Utente di HTML.it
    Registrato dal
    Sep 2008
    Messaggi
    312

    C problema con le fifo

    Salve a tutti,
    ho realizzato una banale applicazione client-server in cui un client scrive su la fifo inizializzata dal server il nome di un file e il nome della fifo dove vuole ricevere la risposta. Il server controlla se è presente il file nella directory corrente e risponde al client con 'Y' o 'N' a seconda se il file sia presente o meno. Le printf che trovate nel codice non hanno funzione specifiche ma sono state messe da me per una sorta di debug. Prima di postare il codice vi dico sin da subito che il client si blocca sulla read, subito dopo aver stampato a video pipe "server".
    codice:
    SERVER
    #include <sys/types.h>
    #include <dirent.h>
    #include <stdio.h>
    #include <fcntl.h>
    #include <signal.h>
    
    /* struttura contenente il messaggio inviato dal client*/
    typedef struct{
    	char  nomePipe[20];
    	char  nomeFile[20];
    }messaggio;
    
    /* controlla se il file è presente nella directory corrente identificata da "."
        se è presente restituisce 1; 0 altrimenti*/
    int presente(char *fileName){
    	int result=1;
    	DIR   *dp;
        struct dirent  *dit;
        dp = opendir(".");printf("ma na capito");
    	while((dit = readdir(dp)) !=NULL){
    		
    		printf("%s",dit->d_name);
    			if(strcmp(dit->d_name,fileName)==0)
    				return result;
    		
    	}
    	result = 0;
    	return result;
    
    }
    
    
    
    int main(){
    	int serverPipe,fd,byte,pid,clientPipe,wr,b,c;
    	messaggio m;
    	char risposta[2];
    	//signal(SIGTERM,disconnetti(m));
    	//signal(SIGINT,disconnetti(m));
    	serverPipe = mkfifo("server",O_CREAT|0666); //creazione FIFO
    	if(serverPipe==-1){
    		printf("Errore nella creazione della named pipe server");
    		exit(0);
    	}
    	fd = open("server",O_RDWR); //apertura FIFO in lettura e scrittura
    	while(1){
    		byte = read(fd,&m,sizeof(messaggio));
    		
    		if(byte!=0){
    			pid = fork();
    			if(pid==0){
    				// sono nel processo figlio		
    				
    				wr = open(m.nomePipe,O_WRONLY);
    				printf("%s\n",m.nomeFile);
    				printf("%s\n",m.nomePipe);
    				if(presente(&m.nomeFile)==1){
    					printf("ciao\n");
    					risposta[0] = 'Y';				
    				   b = write(wr,risposta,2);
    					printf("ciao\n");
    				   close(wr);
    				}  
    				else{
    					printf("prima\n");
    					risposta[0]='N';
    					c = write(wr,risposta,2);
    					close(wr);
    				}
    					
    				   
    				   exit(0);
    			}//prima if
    		}//seconda if
    
    			
    			
    		
    	}
    
    
    }
    void disconnetti(messaggio m){
    	fflush(stdout);
    	unlink(m.nomePipe);
    	printf("fatto\n");
    	exit(0);
    }
    CLIENT
    
    #include <sys/types.h>
    #include <dirent.h>
    #include <stdio.h>
    #include <fcntl.h>
    typedef struct{
    char  nomeFile[20];
    char nomePipe[20];
    }messaggio;
    
    int main(){
    	messaggio m;
    	char response[10];
    	int pipeClient,openServer,a,b,c;
    	printf("Inserire nome del file da trovare\n");
    	scanf("%s",&m.nomeFile);
    	printf("Inserire nome della pipe da creare\n");
    	scanf("%s",&m.nomePipe);
    	// creo pipe client
    	pipeClient = mkfifo(m.nomePipe,O_CREAT|0666);
    	if(pipeClient==-1){
    		printf("non riuscito");
    	}
    	openServer = open("server",O_WRONLY);
    	a = write(openServer,&m,sizeof(m));
    	printf("pipe server\n");
    	close(openServer);
    	b = open(m.nomePipe,O_RDONLY);
    	c = read(b,&response,2);
    	printf("pipe client\n");;
    	close(b);
    	unlink(m.nomePipe);
    	
    	
    
    }

  2. #2
    Utente di HTML.it
    Registrato dal
    Sep 2008
    Messaggi
    312
    per essere precisi è la write all'interno del server che restituisce -1....per cui va in errore. Come mai?

  3. #3
    Secondo me, basta che tu lo verifichi, è che tu apri le fifo o in sola lettura o in sola scrittura. Se tu volessi continuare a farlo in questa maniera (quindi o sola lettura o scrittura) dovresti aggiungere l' opzione non non bloccante, oppure così come ho fatto io in un progetto universitario, di aprire le fifo sia in lettura che scrittura, e poi installarci un lock (quindi una struct flock).
    IMHO è la scelta migliore, in quanto oltretutto la cpu non viene occupata al 100% per la lettura.
    codice:
    /* Settiamo il lock in lettura */  boolean Lock_lettura(int fd) { 	 	struct flock lock; 	int l_ock = -1; 	 	memset(&lock,0,sizeof(struct flock)); 	lock.l_type = F_RDLCK; 	lock.l_whence = SEEK_SET; 	 	l_ock = fcntl(fd,F_SETLKW,&lock); // proviamo ad installare fcntl 	 	if(l_ock < 0) { 		 			perror("Errore input_server"); 			return false; 			 		} 		 	return true; 	 } 	 // Settiamo il lock in scrittura 	 boolean Lock_scrittura(int fd) { 	 	struct flock lock; 	int l_ock = -1; 	 	memset(&lock,0,sizeof(struct flock)); 	lock.l_type = F_WRLCK; 	lock.l_whence = SEEK_SET;	  	l_ock = fcntl(fd,F_SETLKW,&lock); 	  	if(l_ock < 0) { 		 			perror("Errore scrittura"); 			return false; 			 		} 		 	return true; 	 }  // Settiamo le fifo del demone  boolean Set_FIFO_daemon(void) { 	 	if((input_server = open(FIFOtosmmd,O_RDWR))==-1) 		return false;  	if((output_server = open(FIFOfromsmmd,O_RDWR))==-1) { 		 		close(input_server); 		return false; 		 		} 		 	if(Lock_lettura(input_server) == false) 		return false; 		 	if(Lock_scrittura(output_server) == false) 		return false; 		 	return true; 	 }

    Scusami se è indentato male, questo qui è codice estrapolato dal mio progettino e che è perfettamente funzionante, e gestisce bene i lock (appurato dal professore!!!).

  4. #4
    Utente di HTML.it
    Registrato dal
    Sep 2008
    Messaggi
    312
    Questo esempio l'ho preso dalle slides di un professore universitario ed è un paradigma che si trova in svariati siti(per esempio questo http://www.cact.unile.it/facilities/...apilsu183.html). La cosa strana è che non sono le fifo ma non riesco a fare la write.Non sono molto pratico di C e mi viene il dubbio che sbaglio appunto la write in quanto mi restituisce -1, quindi errore.
    Devo inviare sulla fifo un carattere, Y OR N, ho fatto così nel server:
    codice:
    char risposta[2];
    risposta[0] = 'Y';
    risposta[1] = '\0';
    int c = write(wr,&risposta,sizeof(risposta));
    Ovviamente wr è l'identificativo ottenuto dalla open. Quel sizeof è giusto?

  5. #5
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,464
    Controlla il valore di errno dopo la write

    Al posto della sizeof utilizza

    strlen(risposta)+1
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  6. #6
    Utente di HTML.it
    Registrato dal
    Sep 2008
    Messaggi
    312
    Ho cambiato sizeof(risposta) con (strlen)+1 ma il risultato non cambia. Per quanto riguarda il controllo della variabile errno, come si fa?
    Ho provato a fare così ma non stampa nulla:
    codice:
    b = write(wr,&risposta,strlen(risposta)+1);
    if(b==-1)
         printf("%d\n",errno);

  7. #7
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,464
    Originariamente inviato da lio.b
    Ho cambiato sizeof(risposta) con (strlen)+1 ma il risultato non cambia.
    Non te l'ho detto perche' e' la soluzione del tuo problema, ma perche' e' piu' corretta la strlen della sizeof ...

    Per quanto riguarda il controllo della variabile errno, come si fa?
    Ho provato a fare così ma non stampa nulla:
    codice:
    b = write(wr,&risposta,strlen(risposta)+1);
    if(b==-1)
         printf("%d\n",errno);
    Questo e' strano ... forse perche' b non e' -1 ...

    Prova a visualizzare a prescindere dal valore di b
    e dato che risposta e' gia' un puntatore (in quanto e' una stringa), scrivi

    codice:
    b = write(wr, risposta, strlen(risposta)+1);
    printf("%d\n",errno);
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  8. #8
    Utente di HTML.it
    Registrato dal
    Sep 2008
    Messaggi
    312
    Ho stampato errno ed assume valore 9. b è -1 in quanto se faccio:
    codice:
    if(b==-1)
    printf("%d\n",errno)
    riesco a stampare il vlore della variabile

  9. #9
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,464
    Originariamente inviato da lio.b
    Ho stampato errno ed assume valore 9. b è -1 in quanto se faccio:
    Ma non avevi detto che non visualizzava nulla??

    Comunque, se il valore e' 9, ovvero EBADF (Bad File Descriptor), vuol dire che il descrittore che hai usato (wr) non e' corretto. Probabilmente qualcosa non è andata bene quando hai fatto la open. Controlla errno subito dopo la open e che i valori dei parametri passati alla open siano corretti.
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  10. #10
    Utente di HTML.it
    Registrato dal
    Sep 2008
    Messaggi
    312
    Hai ragione, è che una volta me lo stampa questo errno = 9 a volte no.
    Cmq dopo la open assume valore 2. Che significa?

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.