[c] problema multi-client/server

di il
1 risposte

[c] problema multi-client/server

Ciao a tutti, vi scrivo perchè ho un problema per quanto riguarda la comunicazione tra client e server. Devo creare una chat per scambiare messaggi tra diversi client, questi client devono anche potersi registrare, effettuare login e logout. Per quanto riguarda il login e la registrazione sono riuscito a implementare il tutto in maniera funzionante, il problema sorge quando un utente deve fare il logout. Mi spiego meglio, se si connette un solo client il problema non sussiste e il logout avviene correttamente, se invece ne collego 2 il server invia il comando di logout solo all'ultimo client connesso lasciando in attesa indefinita il primo client. Vi posto il codice del thread che effettua queste operazioni e il relativo codice del client

thread del server:
/////////////////////////////////////////////////////////////
//gestione comunicazione col client
void *worker(void *threadarg) { 
	
	char *read_sender, *read_receiver, *read_msglen, *msg;
	char read_msg[80];
	char buffer[1000], risposta[1000];
	char *tok, *key, ret, *token;
	int msglen, i = 0;
	const char *space= " ", s[2] =":";
	int *csd= (int*) threadarg;
	msg_t messaggio;
	hdata_t *trovato;
	FILE *fp;

	memset(buffer, 0 ,1000); //inizializzo a zero i campi del buffer
	memset(read_msg, 0, 80);
	//close(msd); // closing master socket
  
	// leggiamo tutti i dati dalla socket e salviamo in un buffer
	read(*csd, buffer, 1000);
  
	// elaboriamo il buffer per recuperare i campi della struttura
  
	// il primo carattere e' il tipo
	messaggio.type = buffer[0];

	printf("MESSAGGIO.TYPE = %c\n", messaggio.type);
	
	if(messaggio.type == MSG_LOGIN) {
		strtok(buffer, " ");
		msglen = atoi(strtok(NULL, " "));
		msg = strtok(NULL, " ");

		printf("QUELLO CHE HO RICEVUTO: %c %d %s\n", messaggio.type, msglen, msg);

		trovato = CERCAHASH(msg, hash);

		if(trovato != NULL) {
			ret = MSG_OK;
			write(*csd, &ret, sizeof(char));
			trovato->sockid = 1; //utente connesso
		} else {
			ret = MSG_ERROR;
			write(*csd, &ret, sizeof(char));
		}	
	}

	if(messaggio.type == MSG_REGLOG) {
		if((fp = fopen("user-file.txt", "a+")) == NULL) {
			fprintf(stderr, "File non aperto\n");
			exit(1);		
		} else
			printf("aperto con successo\n");

		strtok(buffer, " ");
		msglen = atoi(strtok(NULL, " "));

		// il messaggio potrebbe contenere spazi, quindi ogni token va a comporre il messaggio
		while((tok=strtok(NULL, " ")) != NULL) {
    		if(strlen(read_msg) != 0) // prima di aggiungere il token letto mettiamo uno spazio, ma non all'inzio
				strcat(read_msg,space);
			strcat(read_msg,tok);
		}
		printf("read_msg %s\n", read_msg);
		fprintf(fp, "%s\n", (char*)read_msg); //salvo l'utente appena iscritto sul file
		fflush(fp);
		fclose(fp);

		funzionehash("user-file"); //carico la tabella degli utenti aggiornata

		tok = strtok(read_msg, s); //salvo solo l'username per controllare che la registrazione abbia avuto successo
	
		trovato = CERCAHASH(tok, hash);

		if(trovato != NULL) {
			ret = MSG_OK;
			write(*csd, &ret, sizeof(char));
			trovato->sockid = 1; //utente connesso
		} else {
			ret = MSG_ERROR;
			write(*csd, &ret, sizeof(char));
		}	
	}
	while(go) {
		memset(risposta, 0, 1000);
		read(*csd, buffer, 1000);
		messaggio.type = buffer[0];

		if(messaggio.type == MSG_LIST) {
		} else if(messaggio.type == MSG_BRDCAST) {

		} else if(messaggio.type == MSG_SINGLE) {

		} else if(messaggio.type == MSG_LOGOUT) {
			strtok(buffer, " ");		
			key = strtok(NULL, " ");
			trovato = CERCAHASH(key, hash);

			if(trovato != NULL){
				ret = MSG_OK;
				trovato->sockid = 0; //utente disconnesso
			} else {
				ret = MSG_ERROR;
			}		
			sprintf(risposta, "%c %c", messaggio.type, ret);		
			write(*csd, risposta, sizeof(risposta));
			pthread_exit(NULL);
		}
	}
}
codice del client relativo al logout
	while(go) {
		messaggio.msg = malloc(SL * sizeof(char));
		memset(buffer, 0, 1000); //riazzero il campo buffer
		memset(risposta, 0, 1000); //riazzero il campo buffer
 
		printf("Digita un comando da inviare al server:\n");
		scanf("%s", cmd);
		while(getchar() != '\n');

		if(strcmp(cmd, "ls") == 0) {
			messaggio.type = MSG_LIST;
			strcpy(messaggio.sender, user);
			sprintf(buffer, "%c %s", messaggio.type, messaggio.sender);
				
		} else if(strcmp(cmd, "dest") == 0) {
			printf("digita un destinatario(per inviare il messaggio in broadcast scrivi *)\n");
			scanf("%s", messaggio.receiver);
			while(getchar() != '\n');
			strcpy(messaggio.sender, user);
			if(strcmp(messaggio.receiver, "*")==0){
				messaggio.type = MSG_BRDCAST;
				//messaggio.receiver = NULL;
			} else {
				messaggio.type = MSG_SINGLE;
			}
			printf("Digita il messaggio che vuoi inviare:\n");
			
			fgets(messaggio.msg, 256, stdin);
			messaggio.msglen = strlen(messaggio.msg);
			sprintf(msg_len, "%d", messaggio.msglen);

			sprintf(buffer, "%c %s %s %s %s", messaggio.type, messaggio.sender, messaggio.receiver, msg_len, messaggio.msg);

		} else if(strcmp(cmd, "logout") == 0) {
			messaggio.type = MSG_LOGOUT;
			strcpy(messaggio.sender, user);
			sprintf(buffer, "%c %s", messaggio.type, messaggio.sender);
						
		} else {
			fprintf(stderr, "Errore, comando %s non riconosciuto\n", cmd);
		}
		
		
		printf("BUFFER: %s\n", buffer);

		write(sd, buffer, sizeof(buffer));
	
		read(sd, risposta, sizeof(risposta)); //leggo la risposta

		printf("RISPOSTA %s\n", risposta);

		messaggio.type = risposta[0];

		if(messaggio.type == MSG_LOGOUT) {
			strtok(risposta, " ");
			tok = strtok(NULL, " ");
			strcpy(risp, tok);
			if(risp[0] == MSG_OK) {
				printf("Il server ha tornato %c, disconnessione in corso..\n", risp[0]);
				//close(sd);
				exit(1);
			} else {
				fprintf(stderr, "Il server ha tornato %c, Disconnessione non possibile\n", risp[0]);
			}
		} else if(messaggio.type == MSG_SINGLE) {
		}
	}
spero possiate aiutarmi.

1 Risposte

Devi accedere o registrarti per scrivere nel forum
1 risposte