|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Member
Iscritto dal: Apr 2008
Messaggi: 62
|
[C] Client/Server - Il mio server si rifiuta di accettare piu client, ne vuole uno
Uff!
Il mio elaborato riguarda una videointerrogazione in rete dove il server è il professore mentre i clients sono gli studenti. Il mio problema è che io vorrei che il prof invii inizialmente la prima domanda a tutti gli studenti, poi uno di loro risponde, entra in sez critica, gli altri aspettano lui risponde e quando ha terminato si passa alla domanda successiva. Ciò non avviene O_O Il mio server prende e accetta il primo ... gli manda le domande aspettando le risposte, fa tutti i controlli di correttezza, assegnamento punteggio poi chiude e finisce mentre invece dovrebbe partecipare anche l'altro client. Ho provato ad aprire 3 terminali, dove uno è il server e gli altri due sono i client e non so se magari questo "errore" è dovuto all'esecuzione in locale oppure no ... vi metto il codice ... ditemi, sigh io ho esame l'8 marzo ... sigh grazie anticipatamente CODICE SERVER Codice:
#include <stdio.h> // per I/O #include <stdlib.h> // per exit, malloc, atoi... #include <unistd.h> // per exec, getpid... #include <pthread.h> // thread #include <semaphore.h> //semafori posix #include <sys/types.h> // standard posix #include <netinet/in.h> // #include <sys/socket.h> // socket #include <signal.h> // segnali #include <string.h> #include <pthread.h> #include <sys/types.h> #include <semaphore.h> #include <sys/types.h> #include <semaphore.h> #include <fcntl.h> #define totpost 3 //numero studenti #define MAX 3 //numero domande #define LEN 1024 //caratteri per riga: 1023+0 del messaggio #define PORT 16000 //porta dove il server accetta le connessioni #define semaforo "sem_mutex" #define MACS 2 char domande[MAX][LEN]; //tabella caricata con domande e risposte char risposte[MAX][2]; //tabella caricata con le risposte corrette void *caricamento(void *arg); //funzione svolta dal thread1 char risp[2]; sem_t *mutex; int sd, i, j, k; int punteggi[MAX][MACS], punteggio; int tab[totpost][2]; struct sockaddr_in server_addr; // struttura dati di configurazione struct sockaddr_in client_addr; socklen_t client_len; int main(int argc, char *argv[]) { system("clear"); //system chiama il comando UNIX "clear" printf("Server avviato con pid = %d\n", getpid()); int i; //THREAD int res, pid; pthread_t thread1; //primo thread per il caricamento void *thread_result; res=pthread_create(&thread1, NULL, caricamento,NULL); if (res!=0) { perror("\n****ERRORE CREAZIONE THREAD***\n"); exit(1); } res=pthread_join(thread1, &thread_result); //come la wait printf("thread1 terminato con stato: %d\n", (int*)thread_result); //FINE THREAD //inizializzo il vettore punteggi for(j=0;j<2;j++) for(i=0;i<totpost;i++) { punteggi[i][j]=0; punteggi[i][j]=0; } //fine //VISUALIZZAZIONE DOMANDE PER CONFERMA CARICAMENTO printf("\n\n******ELENCO DOMANDE******\n"); for(k=0;k<MAX;k++) printf("Domanda numero %d:\t%s\nRisposta Corretta:\t%s\n\n",k+1,domande[k],risposte[k]); //SOCKET int client_sd[totpost]; // preparazione dei dati relativi al bind server_addr.sin_family = AF_INET; //dominio server_addr.sin_port = htons(PORT); //host to network server_addr.sin_addr.s_addr = INADDR_ANY; //associa al server l'indirizzo della macchina client_len = sizeof(struct sockaddr_in); //SOCKET int sd=socket(AF_INET, SOCK_STREAM, 0);//restituisce l'identificativo del socket if(sd<0) { perror("creazione socket errata!!\n"); exit(-1); } //BIND printf("Effettuo la bind del socket con la porta ds\n", PORT); if (bind(sd, (const struct sockaddr *) &server_addr, client_len) < 0) { perror("Durante il bind\n"); exit(1); } //LISTEN printf("Mi metto in attesa di connessioni sulla porta %d\n", PORT); if (listen(sd, 2) < 0) { perror("Durante il listen"); exit(1); } printf("Entro nel ciclo for in cui accetto connessioni\n"); // itero il tutto cn un ciclo for ke crea un sd dedicato per ogni client accettato for(i=0;i<totpost;i++) { //ACCEPT: accetta le commessioni che gli arrivano client_sd[i] = accept(sd, (struct sockaddr *) &client_addr, &client_len); if (client_sd[i] < 0) { perror("Durante l'accept\n"); exit(1); } //FORK: creazione figli pid = fork(); if (pid == 0) //FIGLIO { printf("sono il servente: %d\n",getpid()); //figlio ke s collega con il client printf("Connessione con client accettata sul socket %d\n", client_sd[i]); break; } if(pid < 0) //ERRORE { printf("\n\n ERRORE FORK\n\n"); exit(1); } if(pid >0) //PADRE { sleep(2); //ASPETTA LA TERMINAZIONE DEI FIGLI ... MANCU PER METTERE NA WAIT } //CARICAMENTO TABELLE CON IDENTIFICATIVI ... pero' ci son pobbbbbemi tab[i][0]=pid; tab[i][1]=client_sd[i]; } // crea/preleva un semaforo con valore iniziale a 1 (per noi un mutex) mutex = sem_open(semaforo, O_CREAT, 0777, 1); if (mutex == 0) { perror("sem_open"); exit(1); } else { for(k=0;k<MAX;k++) //conta le domande da inviare { printf(" \nInvio la %d domanda ... ", k+1); for(i=0;i<totpost;i++) { if(send(client_sd[i],domande[k],strlen(domande[k]),0)>0) { printf(" \n*********** DOMANDA %d inviata ************ ", k+1); printf("\nAttendo una risposta dagli studenti per circa 10 secondi\n"); sleep(10); //ricevo la prima risposta quindi semaforo rosso per tutti gli altri printf("\n"); printf("Attendo l'acquisizione del mutex\n"); if (sem_wait(mutex) < 0) { perror("Su sem_wait"); exit(1); } printf("Mutex acquisito correttamente\n"); printf("Effettuo tutte le operazioni\n"); res=recv(client_sd[i], risp, 2, 0); if(res>0) { printf("\nRisposta ricevuta: \t %s\n",risp); sleep(3); printf("\n Effettuo il controllo di correttezza sulla risposta\n\n"); if(strcmp(risposte[k],risp)==0) { printf("\nLa risposta corretta è stata data dallo studente con ID %d\n",client_sd[i]); punteggi[i][j]=client_sd[i]; punteggi[i][j+1]++; } } sleep(1); printf("Rilascio il mutex e dormo 1 secondo\n"); if (sem_post(mutex) < 0) { perror("Su sem_post"); exit(1); } } } } } for(i=0;i<totpost;i++) printf("\nEcco i vari punteggi:\n\nID Studente: %d\t Punteggio: %d\n",client_sd[i],punteggi[i][j+1]); close(sd); printf("\n"); printf("\n\t\t ********************* "); printf("\n\t\t * * "); printf("\n\t\t * TERMINATO!!!!! * "); printf("\n\t\t * * "); printf("\n\t\t ********************* "); printf("\n\n"); system("killall -q server"); } //FINE MAIN /*THREAD CONTROLLO MAX E MIN PUNTEGGI void *punteggi(void *args) { int i, j, temp; for (i = (array_size - 1); i >= 0; i--) { for (j = 1; j <= i; j++) { if (numbers[j-1] > numbers[j]) { temp = numbers[j-1]; numbers[j-1] = numbers[j]; numbers[j] = temp; } } } da modificare ma è l'algoritmo bubble sort per ordinare in modo crescente o decrescente il vettore punteggio per decretare il "vincitore" }*/ //THREAD CARICAMENTO DOMANDE void *caricamento(void *args) { char s[1024]; char r[2]; int k; int risp; printf("\n\n******** CARICAMENTO DOMANDE START ******** "); for(k=0; k<MAX; k++) { printf("\nInserisci la %d domanda e le 4 risposte\t \n", k+1); gets(s); if(strlen(s)==0) { printf("\nERRORE: STRINGA VUOTA!! REINSERIRE DATI NELLA DOMANDA"); k--; } else if(strlen(s)>LEN) { printf("\nERRORE: STRINGA GRANDE!! REINSERIRE DATI NELLA DOMANDA"); k--; } else strcpy(domande[k], s); printf("\nInserisci la %d risposta corretta\n", k+1); gets(r); if(strlen(r)==0) { printf("\nERRORE: STRINGA VUOTA NELLA RISPOSTA !! REINSERIRE DATI."); k--; } else if(strlen(r)>1) { printf("\nERRORE: troppi caratteri, inserire una sola lettera nella risposta"); k--; } else strcpy(risposte[k], r); } sleep(3); pthread_exit(EXIT_SUCCESS); } //FINE THREAD CARICAMENTO DOMANDE CODICE CLIENT Codice:
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #define LEN 1024 #define PORT 16000 #define MAX 3 int sd, res, ress, i, j; char risp[2], punt[2]; struct sockaddr_in server_addr; struct hostent *hostinfo; socklen_t len; int main(int argc, char *argv[]) { if (argc < 2) { printf("Utilizzo: ./%s <indirizzo>\nHai dimenticato di inserire l'indirizzo!!! \n", argv[0]); exit(1); } system("clear"); //SOCKET printf("Creo il socket\n"); sd = socket(PF_INET, SOCK_STREAM, 0); if (sd < 0) { perror("Durante la creazione del socket\n"); exit(1); } // prepara i dati per la connessione con il server server_addr.sin_family = AF_INET; server_addr.sin_port = htons(PORT); server_addr.sin_addr.s_addr = INADDR_ANY; hostinfo = gethostbyname(argv[1]); if (hostinfo == NULL) { printf("Non è stato possibile risolvere il nome del server\n"); exit(1); } else server_addr.sin_addr = *((struct in_addr *) hostinfo->h_addr); //CONNECT printf("Apro la connessione\n"); if (connect(sd, (struct sockaddr *) &server_addr, sizeof(struct sockaddr_in)) < 0) { perror("Durante la connect"); exit(1); } //semaforo verde printf(" ***************Ricevo la prima domanda e la visualizzo a schermo****************"); char buffer[MAX][LEN]; for(i=0;i<=MAX;i++) { res=recv(sd, buffer[i], LEN+1,0); if(res>0) { printf("\nLa domanda a cui devi rispondere è: %s \n Inserisci il carattere corrispondente alla tua risposta\n", buffer[i]); gets(risp); sleep(3); res=send(sd, risp, strlen(risp), 0); if (res>0) printf("\n La Risposta Inviata Correttamente è: \t %s\n",risp); } } exit(0); } |
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 21:05.