Problema lettura named pipe in c

di il
3 risposte

Problema lettura named pipe in c

Salve,sto creando questo programma che legge dei dati su un'unica fifo da piu client ma mi da sempre segmentation fault quando nel ciclo infinito cerco di fare una read per la seconda volta.
Ecco qui il codice.

#include <pthread.h>//serve per il multithreading
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h> 
#include <string.h>
#include <stdio.h>

#include <errno.h>//serve per gestione errori
#include <fcntl.h>//serve per le fifo

#include <stdio.h> 
#include <stdlib.h>
 #include <signal.h> 
 #include <string.h>
  #include <unistd.h> 
  #include <fcntl.h>
  #include <sys/types.h> 
  #include <sys/stat.h>
//VARIABILI GLOBALI
int lung_max_msg = 30;
int lung_min_chiave = 3;
int lung_max_chiave = 10;
char nome_server[30];

void* servi(char* nome_client,char* input_messaggio,char* input_chiave,char codec);
//void codificatore(char codec,char* msg,char* chiave,char* risultato);
int main()
{	
	pthread_t pid;
	//pthread_t pid2,pid3;
	char* nome_client;
	int buf = 1000;
	char buffer[300];
	char* tmpcodec;
	char codec;
    char* input_messaggio;
	char* input_chiave;
	int numread;
	int fd ;
	strcpy(nome_server,"miafifo");
	//strcpy(nome_client,"fifo_lettura");
	
	printf("Programma avviato......\n");
	printf("Attesa dei client......\n");

		
	 //CREAO LA FIFO PER LEGGERE LE RICHIESTE DAI CLIENT
		int ret_val = mkfifo(nome_server,0777);
		if((ret_val == -1) && (errno != EEXIST))
		 {
			 perror("Errore durante la creazione della fifo!");
			 exit(1);
		 }
		 printf("Ho creato la FIFO\n");
		 //apro la fifo
		 fd = open(nome_server,O_RDWR);
		 printf("------Ho aperto la FIFO SERVER-------- \n");
		 
		 
	 
while(1)//continuo a cercare di leggere la fifo per vedere se ci sono altri client da servire
{ 		
		printf("sto per leggere...\n");
		 numread = read(fd,&buffer,buf); // <----- PROBLEMA al secondo ciclo siccome esegue la servi().....

		 if(numread < 0)
		 {
			 perror("Errore lettura buffer!\n");
			 exit(1);
		 }
		 printf("\nIl buffer contiene :  \"%s\"\n",buffer);
		
if(strcmp(buffer,"") !=  0)
{
	
		printf("nuovo client..\n");
		//prelevo nome_client,messaggio,chiave e codec
		nome_client = strtok(buffer,"$");
		input_messaggio = strtok(NULL,"$");
		input_chiave = strtok(NULL,"$");
		tmpcodec = strtok(NULL,"$");
		
		codec = tmpcodec[0];
		printf("Ho prelevato i dati...\n");
		printf("Nome client = %s \n",nome_client);
		printf("Ho letto tutti i dati\n");
		//creao un thread per gestire il client
		pthread_create(&pid,NULL,servi(nome_client,input_messaggio,input_chiave,codec),NULL);
		//printf("Ho finito l'esecuzione del thread....\n");
		//pthread_join(pid,NULL);
		//printf("Ho chiuso la fifo del server....\n");
		//strcpy(buffer,"");
		//close(fd);//chiudo la fifo del  server
		printf("Primo client servito..\n");
		
}	   
	   
	   
	  // memset(buffer,0,sizeof(buffer));
	 strcpy(buffer,"");
}//fine while(1)


	printf("Sto chiudendo il server.....\n");
	
	
	//unlink(fd);
	exit(0);
}
void codificatore(char codec,char* msg,char* chiave,char* ris,int lung_msg,int lung_chiave)
{
	printf("Entro nella procedura codificatore()\n");
	printf("\ncodec = %c ,msg = %s ,chiave = %s ,ris = %s ,lung_msg = %d ,lung_chiave = %d \n\n\n",codec,msg,chiave,ris,lung_msg,lung_chiave);
	
	
	int maiuscolo;
	int i,j;
   for(i = 0,j=0; i < lung_msg;i++)
	{
		//controllo se nel risultato la letterA sara maiuscola o minuscola 
		//printf("ciclo for i = %d \n",i);
	    if(isupper(msg[i]))
	    {
			maiuscolo = 1;
		}
		else
		{
			maiuscolo = 0;
		}
		//trasformo tutto in minuscolo per fare piu semplicemente le operazioni di calcolo e traslitterazione
		//printf("Trasformo tutto in minuscolo\n");
		msg[i] = tolower(msg[i]);
		chiave[i] = tolower(chiave[i]);
		//printf("Ho fatto una trasformazione...\n");
		if( msg[i] == ' ') 
		{
		   ris[i] = ' ';
		   //printf("  ");
		}
		else
		{	
			//printf("Stampo dei valoti per il testing...\n");
			//printf("%d,",msg[i] - 96);
			//printf("ho stampato un valore...\n");
			//printf("%d",chiave[j] - 96);  //<----- segmentation fault!!!!!!!!!!!
			//printf("Ho finito di stampare...\n");
			
			
			//printf("controllo chiave\n");
			if(chiave[j] != ' ')
			{
				//printf("entro nel ciclo...\n");
				if(codec == '1')
				{
					//printf("Inzio la codificazione di una lettera\n");
					//questa trasformazione deve funzionare anche su codifiche diverse
				   ris[i] = ( ((msg[i] - 96 ) + (chiave[j] - 96 )) % 26) + 96; 
				   //printf("Ho fatto la codifica di una lettere!\n"); 
				}
				else
				{
					
					ris[i] = ( ((msg[i] - 96 ) - (chiave[j] - 96 )));//+ 96;
					if(ris[i] < 1)
					{
						ris[i] = 26 + ris[i];
						
					}
					printf(" : %d,",ris[i] );
					ris[i]+= 96;
				}
				
				
			}
			else
			{
					ris[i] = ' ';
			}
			   
			if(maiuscolo)
			{
				ris[i] = toupper(ris[i]);
			}
				
			j = (j + 1) % lung_chiave;
		}	
	//printf("\n\n");
	}
	
	ris[lung_msg] = '\0';
	//stampa RISULTATO
	
}
void* servi(char* nome_client,char* input_messaggio,char* input_chiave,char codec)
{
	
	printf("Etro in servi()\n");
	char msg[31];
	char chiave[11];
    char ris[30];
	int m;
    char errore_input = '0';
    char msg_errore[300];

	//creao la fifo per mandare dati al client
	
     int fb = open(nome_client,O_WRONLY);	
	 printf("Ho aperto la FIFO per la scrittura.....\n");

	//CONTROLLO DATI IN INPUT
	int lung_chiave = strlen(input_chiave);
	int lung_msg = strlen(input_messaggio);
	char* tmperror[10];
	strcpy(msg_errore,"");
	if(lung_msg > lung_max_msg)
	{
		sprintf(tmperror,"%d",lung_max_msg);
		strcat(msg_errore,"\n\nLunghezza massima messaggio  = ");
		strcat(msg_errore,tmperror);
		errore_input = '1';
	}
	if(lung_chiave < lung_min_chiave)
	{
		sprintf(tmperror,"%d",lung_min_chiave);
		strcat(msg_errore,"\n\nLunghezza minima chiave = ");
		strcat(msg_errore,tmperror);
		errore_input = '1';		
	}
	if(lung_chiave > lung_max_chiave)
	{
		sprintf(tmperror,"%d",lung_max_chiave);
		strcat(msg_errore,"\n\nLunghezza massima chiave = ");
		strcat(msg_errore,tmperror);
		errore_input = '1';		
	}	
	strcpy(msg,input_messaggio);
	strcpy(chiave,input_chiave);

//funzione che codifica il messaggio
//char ascii ->stampabili iniziano dal numero  32 al 126
if(errore_input == '0')
{
	printf("\nSto elaborando il msg!\n\n");
	sleep(1);
	
	//INVIO TUTTI I DATI ALLA FUNZIONE CHE CODIFICA DECODIFICA
//void codificatore(char codec,char* msg,char* chiave,char* ris,int lung_msg,int lung_chiave)

	codificatore(codec,msg,chiave,ris,lung_msg,lung_chiave);
	
	printf("Risultato :  ");
	for(m = 0;m < lung_msg; m++)
	{
		printf("%c ",ris[m]);
	}
}//fine controllo errore input


//ORA INVIO IL RISULTATO AL CLIENT    
if(errore_input == '1')
{
	printf("\nERRORE:%s\n",msg_errore);
	
	write(fb,"34$",3);//indico al client che c'è stato un errore
	write(fb,msg_errore,strlen(msg_errore));
	write(fb,"$",1);
	
}	
else//invio il risultato al client
{
	
	write(fb,"27$",3);//indico al cient che il risultato è corretto e no ci sono errori
	write(fb,ris,strlen(ris));
	write(fb,"$",1);
	
	printf("\nRisultato inviato al client\n");
}


//chiusura fifo

//close(fb);
printf("\n-------------------------------------------------------------------------\n");

	sleep(1);
}

3 Risposte

  • Re: Problema lettura named pipe in c

    Un suggerimento: fai un programma di prova in cui elimini (commenti) tutte le parti di gestione del comando/messaggio ricevuto e di risposta, in modo da arrivare ad uno scheletro che semplicemente riceve i messaggi, li legge e li stampa a video così come sono.
    Se il problema persiste sarà più facile risolverlo!
  • Re: Problema lettura named pipe in c

    Ho provato a togliere la creazione di un nuovo thread per la gestione dei dati da inviare al client e adesso tutto funziona qundi il problema deve avere a che fare con il threading.
    Praticamente adesso chiamo direttamente la funzione servi.
    Pero vorrei capire perché adesso funziona e prima no.E molto strano.
  • Re: Problema lettura named pipe in c

    Per trovare l'inghippo, devi procedere con una modifica alla volta: per esempio ora, dalla situazione funzionante, potresti richiamare la servi() da thread facendo in modo di aspettare comunque la fine di servi() prima di proseguire (magari semplicemente con uno sleep() adeguatamente lungo).
    A mio avviso, comunque, non dovresti gestire su due thread diversi la ricezione dei comandi e la spedizione delle risposte.
Devi accedere o registrarti per scrivere nel forum
3 risposte