PDA

Visualizza la versione completa : [C] problema client-server


rossfe92
17-09-2013, 15:58
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.

boots
18-09-2013, 11:13
Difficile dare una risposta senza codice.
posta almeno la parte client/server che ti da problemi

rossfe92
18-09-2013, 13:31
Non riesco a postarti proprio tutto il codice perchè è molto articolato....
Questo è lo "scheletro":



/* 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.

boots
19-09-2013, 10:20
Andando ad intuito, non vedo errori... potresti postare il client ?

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

rossfe92
19-09-2013, 15:07
Come per il server ti posto il client:



/*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.

boots
20-09-2013, 10:29
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:



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 :D

rossfe92
20-09-2013, 17:44
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à :)

Loading