Visualizzazione dei risultati da 1 a 7 su 7
  1. #1

    [C] problema client-server

    Ciao, sono nuova del forum... avrei bisogno di un aiuto...
    Sto realizzando, per un progetto per l'università, un' applicazione per una chat in c. In sostanza ho un client e un server: il server viene avviato e rimane in attesa di un messaggio di login da parte dell'utente. Quando questo avviene, il server avvia un thread worker che si occupa di eseguire varie operazioni secondo il tipo di messaggio inviato (di login, di list degli utenti connessi, di registrazione...). Se il login avviene con successo, il server invia un messaggio al client. Quando il client riceve tale messaggio, si avviano due thread: un thread reader e un thread writer. Il primo si occupa di leggere i messaggi in arrivo dal server, il secondo di inviare messaggi al server.
    Tutto ciò all'inizio mi funziona: i client riescono a collegarsi. Però il client riesce ad inviare un solo messaggio al server dopo non funziona più. Faccio un esempio: il client invia un messaggio al server con una richiesta di list degli utenti connessi e il server, elaborata la richiesta, invia la sua risposta al client. Però se dopo il client invia di nuovo questa richiesta, il server non riceve nulla.
    Come posso risolvere?? Grazie in anticipo.

  2. #2
    Utente di HTML.it L'avatar di boots
    Registrato dal
    Oct 2012
    Messaggi
    1,626
    Difficile dare una risposta senza codice.
    posta almeno la parte client/server che ti da problemi

  3. #3
    Non riesco a postarti proprio tutto il codice perchè è molto articolato....
    Questo è lo "scheletro":

    codice:
    /* Funzione del thread worker */
    void * thr_worker(void * argv)
    {
    	char * buffer, *buf;
    	buffer = calloc(256, sizeof(char));
            buff = calloc(256, sizeof(char));
    		
    	while(go)
        	{
    		if(mess->type == MSG_LOGIN)
           		{
    			printf("Login\n");
    			/* codice per il login*/
                            buff = msgserver_pack(mess_server->type, mess_server->msg, NULL, NULL); 
                            write(newsockfd, buff, 256*sizeof(buff));
    		}
    		else if(mess->type == MSG_LOGOUT)
           		{
                            printf("Logout\n");
    			/* codice per il logout*/
                            buff = msgserver_pack(mess_server->type, mess_server->msg, NULL, NULL); 
                            write(newsockfd, buff, 256*sizeof(buff));
    		}
                	else if(mess->type == MSG_REGLOG)
           		{
                            printf("Registrazione e login\n");
    			/* codice per il reg-log*/
                            buff = msgserver_pack(mess_server->type, mess_server->msg, NULL, NULL); 
    			write(newsockfd, buff, 256*sizeof(buff));
    		}
    		else if(mess->type == MSG_LIST)
           		{
    			printf("List\n");
                            buff = msgserver_pack(mess_server->type, mess_server->msg, NULL, NULL); 
    			write(newsockfd, buff, 256*sizeof(buff)); 
    		}
                   	else 		//il server riceve un messaggio MSG_SINGLE o MSG_BRDCAST
    		{
    			printf("messaggio\n");
    			if(mess->type == MSG_SINGLE) 
    				richiesta = mess->receiver;	
                            else 						
    				richiesta = "broadcast";		
    			inizializza(&buffer_circolare);		//inizializzo il buffer circolare
    			inserisci(&buffer_circolare, richiesta); //inserisco la richiesta su un buffer circolare
    			if((pthread_create(&dispatcher, NULL, thr_dispatcher, NULL))<0)        
                            //creazione del thread dispatcher
    			{
    				fprintf(stderr,"Errore!! Thread dispatcher non creato!!");
    				exit(1);
    			}
    		}
    		recv(newsockfd, buffer, 256*sizeof(buffer),0);
    		mess = (msg_t *) malloc(sizeof(msg_t));
    		mess = msg_unpack(buffer);
    	}
    	pthread_exit(NULL);
    }
    I messaggi sono costituiti da una struct e, per inviarli tramite socket internet, ho creato delle funzioni msg_pack e msg_unpack per impacchettare e per spacchettare il messaggio in un buffer. Premetto che il resto del codice funziona perchè l'ho provato a parte.

  4. #4
    Utente di HTML.it L'avatar di boots
    Registrato dal
    Oct 2012
    Messaggi
    1,626
    Andando ad intuito, non vedo errori... potresti postare il client ?

    Hai provato a stampare il contenuto del buffer subito dopo la recv() ?

  5. #5
    Come per il server ti posto il client:

    codice:
    /*funzione del thread di scrittura*/
    void * thr_writer(void * argv)
    {
    	buffer = (msg_t *) malloc(sizeof(msg_t));
    	buff = calloc(256, sizeof(char));
    		
    	while(go)
    	{
    		/* a seconda del tipo di messaggio desiderato strutturo buffer*/
    
    		//invio il messaggio
    		buff = msgclient_pack(buffer->type, buffer->msg, buffer->sender, buffer->receiver);
    		write(sock, buff, 256*sizeof(buff));
    		buffer = (msg_t *) malloc(sizeof(msg_t));
    	}
    	return NULL;		
    }
    
    /*funzione del thread di lettura*/
    void * thr_reader(void * argv)
    {
    
    	buffer = (msg_t *) malloc(sizeof(msg_t));
    	buff_rd = calloc (256, sizeof(char));
    			
    	while(go)
    	{
    		rv_byte = recv(sock, buff_rd, 256*sizeof(buff_rd), 0);
    		if (rv_byte != 0 && rv_byte!= -1)  
    		{
    			buffer = msg_unpack(buff_rd); 
    			if (buffer->type == MSG_BRDCAST)
    			{
    				/* printf contenuto messaggio */
    			}
    			else if (buffer->type == MSG_SINGLE) 
    			{
    				/* printf contenuto messaggio */
    			}
    			else if (buffer->type == MSG_LIST)
    			{
    				/* printf lista utenti connessi */
    			}
    		}
    		buffer = (msg_t *) malloc(sizeof(msg_t));
    	} 
    	return NULL;
    }
    Ho provato a stampare il contenuto dopo la recv: quando, dopo il login, invio, ad esempio, un messaggio di list, mi stampa appunto la richiesta inviata dal client; se ripeto l'operazione non stampa nulla. Aggiungo che prima avevo anche provato ad utilizzare la read al posto della recv.

  6. #6
    Utente di HTML.it L'avatar di boots
    Registrato dal
    Oct 2012
    Messaggi
    1,626
    Così, non mi pare ci siano errori...ma visto che il codice non è completo non posso aiutarti più di tanto
    Quello che posso consigliarti è di mettere delle printf() (soprattutto prima/dopo le recv/write) per vedere il flusso di esecuzione.

    PS:

    codice:
    void * thr_reader(void * argv)
    {
    
    	buffer = (msg_t *) malloc(sizeof(msg_t));
    	buff_rd = calloc (256, sizeof(char));
    			
    	while(go)
    	{
    		....
    		buffer = (msg_t *) malloc(sizeof(msg_t));
    	} 
    	return NULL;
    }
    Attenzione che allochi ad ogni ciclo della memoria, ma non la liberi. Se per caso lo fai nel codice omesso, ignora questo PS

  7. #7
    Purtroppo anche mettendo stampe ovunque non riesco a capire l'errore: tutto sembra funzionare bene, ma dopo il secondo messaggio si blocca. Cmq nella parte di codice omessa faccio solo degli assegnamenti, stampe, ecc. niente di particolare...

    Ti ringrazio cmq dei consigli e della disponibilità

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.