Guardie e Ladri client/server

di il
22 risposte

22 Risposte - Pagina 2

  • Re: Guardie e Ladri client/server

    Ciao phatejoker,

    Hai scritto una fork bomb

    Per eseguire fork multiple usa semplicemente un ciclo dove internamente mandi il CHILD nella rispettiva funzione di competenza.
    Per la chiusura puoi usare la wait sul processo genitore la quale attende l'uscita del figlio.
    Come nella creazione, cicli per il numero dei CHILD. Niente kill, niente segnali. La wait ti restituisce il PID del CHILD (se ti serve... ma serve?!) ma soprattutto restituisce il valore della _EXIT del figlio ed ancora tramite le MACRO definite nella sys/wait.h puoi anche controllare eventuali SEGNALI di errore.

    Se vuoi un esempio fammi sapere
  • Re: Guardie e Ladri client/server

    Ho risolto anche quel problema ma adesso ne ho un altro... Quando uno dei due client fa uno spostamento poi l'altro inizia a disegnare dal punto in cui si era fermato il primo... E non riesco a capire perchè. Non avevo visto il tuo messaggio altrimenti penso che mi sarei risparmiato precchia fatica
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netdb.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <ctype.h>
    #include <sys/times.h>
    
    #define SERVER_PORT 1025
    #define MAX_CONN 10
    #define MAXX 20
    #define MAXY 12
    
    
    struct pos {      	//rappresentazione delle coordinate del personaggio
    	char c;
    	int x;
    	int y;
    };
    
    int collision (struct pos a, struct pos b){			// verifica se le due posizioni coincidono
    	if((a.x == b.x) && (a.y == b.y)) 
    		return 1;
    	else 
    		return 0;
    }
    
    void cladro(int guardia, int ladro){
    struct pos  pladro;
    pladro.x=MAXX;
    pladro.y=MAXY;
    pladro.c='$';
    while(1){
    	if(recv(ladro, &pladro, sizeof(pladro),0) > 0){
    		printf("ricevuto ladro\n");
    		printf("%c %d %d \n", pladro.c, pladro.x, pladro.y);
    	}
    	if(send(guardia, &pladro, sizeof(pladro),0) > 0)
    		printf("inviato guardia\n\n");
    }
    }
    
    void cguardia(int guardia, int  ladro){
    struct pos pguardia;
    pguardia.x=0;
    pguardia.y=0;
    pguardia.c='#';
    while(1){
    	if(recv(guardia, &pguardia, sizeof(pguardia),0) > 0){
    		printf("ricevuto guardia\n");
    		printf("%c %d %d \n", pguardia.c, pguardia.x, pguardia.y);
    	}
    	if(send(ladro, &pguardia, sizeof(pguardia),0) > 0)
    		printf("inviato ladro\n\n");
    }
    }
    
    
    void startgame (int guardia, int ladro){
    	int  pid_game;
    	send(guardia, "Sei la guardia\n", 15, 0);
    	send(ladro, "Sei il ladro\n", 13, 0);
    	usleep(100000);
    	send(guardia, "#",1,0); 
    	send(ladro, "$",1,0);
    	usleep(100000);
    		switch (pid_game = fork()){
    			case -1:
    				perror("Errore nell'esecuzione della fork (ladro)");
    				exit(4);
    			case 0: cladro(guardia, ladro);
    			default: cguardia(guardia, ladro);
    				
    				
    		}
    		kill(pid_game, 1);	
    	send(guardia, "Hai vinto!\n", 11, 0);
    	send(ladro, "Hai perso!\n", 11, 0);	
    }
    
    
    int main (int argc, char **argv) {
    	int sock, fdguardia, fdladro, pid_gioco;
    	int waiting=0;
    	char prev='l';
    	struct sockaddr_in server;
    	if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    		perror("chiamata alla system call socket fallita");
    		exit(1);
    	}
    	server.sin_family = AF_INET;
    	server.sin_addr.s_addr = htonl(INADDR_ANY);
    	server.sin_port = htons(SERVER_PORT);
    	if (bind(sock, (struct sockaddr *)&server, sizeof server) == -1) {
    		perror("chiamata alla system call bind fallita");
    		exit(2);
    	}
    	listen(sock, MAX_CONN);
    	/* gestione delle connessioni dei clienti */
    	printf("Server avviato correttamente\n");
    	while (1) {
    		if (prev == 'l'){
    			if ((fdguardia = accept(sock, NULL, 0)) < 0) { 
    				perror("accepting connection");
    				exit(3);
    			}
    			prev = 'g';
    		}
    		else{
    			if ((fdladro = accept(sock, NULL, 0)) < 0) { 
    				perror("accepting connection");
    				exit(3);
    			}
    			prev = 'l';
    		}		
    		waiting++;
    		printf("ricevuta una connessione\n");
    		if (waiting >1){
    			waiting = waiting - 2;
    			switch (pid_gioco = fork()){
    				case -1:
    					perror("Errore nell'esecuzione della fork (startgame)");
    					exit(4);
    				case 0:
    					printf("avvio startgame\n");
    					startgame(fdguardia, fdladro);			
    			}
    	
    		} else 
    			send(fdguardia, "Ricerca giocatori in corso...\n", 31, 0);			
    	}
    	printf("Shutdown server\n");
    	close (sock);
    }
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netdb.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <ctype.h>
    #include <sys/times.h>
    #include <curses.h>
    
    
    #define SERVER_PORT 1025
    #define MAXX 80
    #define MAXY 22
    #define SU 65
    #define GIU 66
    #define SINISTRA 68
    #define DESTRA 67
    
    struct pos {      	//rappresentazione delle coordinate del personaggio
    	char c;
    	int x;
    	int y;
    };
    
    
    void visualizza (struct pos nuovo, struct pos vecchio){
    	mvaddch(vecchio.y, vecchio.x, ' ');
    	mvaddch(nuovo.y, nuovo.x, nuovo.c);
    	curs_set(0);
    	refresh();
    }
    
    void aggiorna (int server, char ruolo){
    	struct pos miapos, miavec;
    	switch (ruolo){	
    		case '#':
    			miapos.x=0;
    			miapos.y=0;
    			miapos.c='#';
    			break;
    		default :
    			miapos.x=MAXX;
    			miapos.y=MAXY;
    			miapos.c='$';
    			break;	
    	} 
    	miavec.x=miapos.x;
    	miavec.y=miapos.y;
    	miavec.c=miapos.c;
    	while(1){
    		char c;
    		switch(c = getch()) {
    			case SU:
    				if(miapos.y>0)
    					miapos.y-=1;
    				break;
    			case GIU:
    				if(miapos.y<MAXY-1)
    					miapos.y+=1;	
    				break;
    			case SINISTRA:
    				if(miapos.x>0)
    					miapos.x-=1;
    				break;
    			case DESTRA:
    				if(miapos.x<MAXX-1)
    					miapos.x+=1;
    				break;
    		}
    		if(send(server, &miapos, sizeof(miapos), 0) > 0){
    			visualizza(miapos, miavec);
    			miavec.x=miapos.x;
    			miavec.y=miapos.y;
    		}else{
    			perror("errore di ricezione in aggiorna");
    			exit(5);
    		}
    	}
    }
    
    void ricevi (int server, char ruolo){
    	struct pos suapos, suavec;
    	switch (ruolo){	
    		case '#':
    			suapos.x=MAXX;
    			suapos.y=MAXY;
    			suapos.c='$';
    			break;
    		default :
    			suapos.x=0;
    			suapos.y=0;
    			suapos.c='#';
    			break;	
    	} 
    	suavec.x=suapos.x;
    	suavec.y=suapos.y;
    	suavec.c=suapos.c;
    	while(1){
    		if(recv(server, &suapos, sizeof(suapos), 0) > 0){
    			visualizza(suapos, suavec);
    			suavec.x=suapos.x;
    			suavec.y=suapos.y;
    		}else{
    			perror("errore di ricezione in ricevi");
    			exit(5);
    		}
    	}
    }
    
    void startgame (int server){
    	struct pos miapos, suapos;
    	int pid_gioco,  j;
    	char buf [11], ruolo;
    	for (j=0; j<31; j++)
    		buf[j]='\0';
    	printf("attesa paramentri\n");
    	if(recv(server, &buf, sizeof(buf), 0) < 0){
    		perror("errore di ricezione in startgame");
    		exit(4);
    	}
    	ruolo=buf[0];
    	/*switch (ruolo){	
    		case '#':
    			miapos.x=0;
    			miapos.y=0;
    			miapos.c='#';
    			suapos.x=MAXX;
    			suapos.y=MAXY;
    			suapos.c='$';
    			break;
    		default :
    			miapos.x=MAXX;
    			miapos.y=MAXY;
    			miapos.c='$';
    			suapos.x=0;
    			suapos.y=0;
    			suapos.c='#';
    			break;	
    	} */
    	printf("%s \n",buf);
    	printf("ricevuti paramentri\n");
    	initscr();
    	noecho();
    	curs_set(0);
    	switch (pid_gioco = fork()){
    		case -1:
    			perror("Errore nell'esecuzione della fork (gioco)");
    			exit(5);
    		case 0:	ricevi(server, ruolo);
    			
    		default: aggiorna(server, ruolo);	
    								
    	}
    	kill(pid_gioco,1);
    }
    
    
    int main () {
    	int sock, server_len, j;
    	struct sockaddr_in server;
    	char buf [31];
    	//creazione socket
    	if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    		perror("chiamata alla system call socket fallita");
    		exit(1);
    	}
    	server.sin_family = AF_INET;
    	server.sin_addr.s_addr = htonl(INADDR_ANY);
    	server.sin_port = htons(SERVER_PORT);
    	//connessione al server
    	server_len = sizeof(server);
    	if (connect(sock, (struct sockaddr *)&server, server_len) < 0) { 
    		perror("accepting connection");
    		exit(2);
    	}
    	do {
    		for (j=0; j<31; j++)
    			buf[j]='\0';
    		if (recv(sock, &buf, sizeof(buf), 0) < 0) {
    			perror("rcv error in main");
    			exit(3);	
    		} else printf("%s\n", buf);
    	}while(buf[0] != 'S');
    	printf("avvio startgame\n");
    	startgame(sock);
    }
    
  • Re: Guardie e Ladri client/server

    Risolto pure questo XD mi manca solo da realizzare il timer. Avevo pensato ad un processo che eseguisse una usleep per tutto il tempo del timer ma non è preciso (ad esempio massimo di 10 secondi per partita mi lascia giocare anche per un minuto...). Come potrei fare?
  • Re: Guardie e Ladri client/server

    Risolto pure questo XD mi manca solo da realizzare il timer. Avevo pensato ad un processo che eseguisse una usleep per tutto il tempo del timer ma non è preciso (ad esempio massimo di 10 secondi per partita mi lascia giocare anche per un minuto...). Come potrei fare?
    Si, l'idea secondo me è corretta ed anche pulita.
    Nel PARENT attendi l'uscita del processo timer e chiudi la connessione. Gli altri CHILD dovrebbero restituire un signal che intercetti.
    Mi piace
  • Re: Guardie e Ladri client/server

    Ci sto provando ma non riesco a capire come scrivere il client ed il server... Io per ora sul server faccio 3 fork (una crea un processo che gestisce la comunicazione con la guarda, una comunica col ladro e la terza si occupa del timer), ed il padre esegue una wait() (quindi dovrebbe aspettare il termine di uno dei suoi figli) e dopodichè chiude le connessioni facendo close(guardia) e close(ladro). La partita però non termina allo scadere del timer ma solo quando la guarda "prende" il ladro. In più, il server non crea più nuove partite se arrivano altre connessioni (mentre nella versione senza timer lo faceva senza problemi).
    Questi sono i codici della versione senza timer:

    client:
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netdb.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <ctype.h>
    #include <sys/times.h>
    #include <curses.h>
    
    
    #define SERVER_PORT 1025
    #define MAXX 50
    #define MAXY 18
    #define SU 65
    #define GIU 66
    #define SINISTRA 68
    #define DESTRA 67
    
    struct pos {      	//rappresentazione delle coordinate del personaggio
    	char c;
    	int x;
    	int y;
    };
    
    struct pos miapos, suapos;
    
    void visualizza (int pipein){ //aggiorna le posizioni a video
    	struct pos sup, miavec, suavec;
    	miavec=miapos;
    	suavec=suapos;	
    	do {
    		read(pipein,&sup,sizeof(sup));
    		if(sup.c == miapos.c){
    			mvaddch(miavec.y,miavec.x,' ');
    			miavec=miapos;
    			miapos=sup;
    		}else{	
    			mvaddch(suavec.y,suavec.x,' ');
    			suavec=suapos;
    			suapos=sup;
    		}
    		mvaddch(sup.y, sup.x, sup.c);
    		curs_set(0);
    		refresh();
    	} while (miapos.x != suapos.x || suapos.y != miapos.y);
    }
    
    void aggiorna (int server, int pipeout){ 
    	struct pos mia;
    	mia=miapos;
    	while(1){
    		char c;
    		switch(c = getch()) {
    			case SU:
    				if(mia.y>0)
    					mia.y-=1;
    				break;
    			case GIU:
    				if(mia.y<MAXY-1)
    					mia.y+=1;	
    				break;
    			case SINISTRA:
    				if(mia.x>0)
    					mia.x-=1;
    				break;
    			case DESTRA:
    				if(mia.x<MAXX-1)
    					mia.x+=1;
    				break;
    		}
    		if(send(server, &mia, sizeof(mia), 0) > 0){
    			write(pipeout,&mia,sizeof(mia));
    		}else{
    			perror("errore di ricezione in aggiorna");
    			exit(5);
    		}
    	}
    }
    
    void ricevi (int server, int pipeout){
    	struct pos sua;
    	sua=suapos;
    	while(1){
    		if(recv(server, &sua, sizeof(sua), 0) > 0){
    			write(pipeout,&sua,sizeof(sua));
    		}else{
    			perror("errore di ricezione in ricevi");
    			exit(5);
    		}
    	}
    }
    
    int main () {
    	int sock, server_len, j;
    	struct sockaddr_in server;
    	char buf [31];
    	//creazione socket
    	if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    		perror("chiamata alla system call socket fallita");
    		exit(1);
    	}
    	server.sin_family = AF_INET;
    	server.sin_addr.s_addr = htonl(INADDR_ANY);
    	server.sin_port = htons(SERVER_PORT);
    	//connessione al server
    	server_len = sizeof(server);
    	if (connect(sock, (struct sockaddr *)&server, server_len) < 0) { 
    		perror("accepting connection");
    		exit(2);
    	}
    	do {
    		for (j=0; j<31; j++)
    			buf[j]='\0';
    		if (recv(sock, &buf, sizeof(buf), 0) < 0) {
    			perror("rcv error in main");
    			exit(3);	
    		} else printf("%s\n", buf);
    	}while(buf[0] != 'S');
    	printf("avvio startgame\n");
    	usleep(5000000);
    //-------------------------------------------------------
    
    	int pid_gioco, pid_play;
    	char ruolo;
    
    	for (j=0; j<31; j++)
    		buf[j]='\0';
    
    	printf("attesa paramentri\n");
    	if(recv(sock, &buf, sizeof(buf), 0) < 0){
    		perror("errore di ricezione in startgame");
    		exit(4);
    	}
    	ruolo=buf[0];
    	printf("%s \n",buf);
    	switch (ruolo){	
    		case '#':
    			miapos.x=0;
    			miapos.y=0;
    			miapos.c='#';
    			suapos.x=MAXX;
    			suapos.y=MAXY;
    			suapos.c='$';
    			break;
    		default :
    			miapos.x=MAXX;
    			miapos.y=MAXY;
    			miapos.c='$';
    			suapos.x=0;
    			suapos.y=0;
    			suapos.c='#';
    			break;	
    	} 
    	printf("ricevuti paramentri\n");
    	
    	initscr(); /* inizializzazione dello schermo */
    	noecho();  /* i caratteri corrispondenti ai tasti premuti non saranno visualizzati sullo schermo del terminale */
    	
    	mvaddch(miapos.y, miapos.x, miapos.c);
    	mvaddch(suapos.y, suapos.x, suapos.c);
    	curs_set(0);
    	refresh();
    	int filedes[2];
    	if(pipe(filedes)==-1) {
    		perror("Errore nella creazione della pipe.");
    		exit(6);
    	}
    
    	switch (pid_gioco = fork()){
    		case -1:
    			perror("Errore nell'esecuzione della fork (gioco)");
    			exit(5);
    		case 0:	close(filedes[0]);
    			ricevi(sock, filedes[1]);
    			
    		default: 
    			switch (pid_play = fork()){
    				case -1:
    					perror("Errore nell'esecuzione della fork (gioco)");
    					exit(5);
    				case 0:	close(filedes[0]);	
    					aggiorna(sock, filedes[1]);
    			
    				default: close(filedes[1]); 
    					 visualizza(filedes[0]);
    			}								
    	}
    	kill(pid_gioco,1);
    	kill(pid_play,1);
    	endwin();
    	if(miapos.x==suapos.x && miapos.y==suapos.y && miapos.c=='#')
    		printf("\nCongratulazioni hai vinto\n\n");
    	else
    		printf("\nTi sei fatto prendere, hai perso\n\n");
    //-------------------------------------------------------
    
    }
    
    server:
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netdb.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <ctype.h>
    #include <sys/times.h>
    
    #define SERVER_PORT 1025
    #define MAX_CONN 10
    #define MAXX 50
    #define MAXY 18
    
    
    struct pos {      	//rappresentazione delle coordinate del personaggio
    	char c;
    	int x;
    	int y;
    };
    
    struct pos pguardia, pladro;
    
    
    void cladro(int guardia, int ladro){//riceva da un clinet e invia dati all'altro
    struct pos sup;
    do{
    	if(pguardia.x!=pladro.x || pguardia.y!=pladro.y){
    	if(recv(ladro, &pladro, sizeof(pladro),0) > 0){
    		printf("ricevuto ladro\n");
    		printf("%c %d %d \n", pladro.c, pladro.x, pladro.y);
    	}
    	sup = pladro;
    	if(send(guardia, &sup, sizeof(sup),0) > 0){
    		printf("inviato guardia\n");
    		printf("%c %d %d \n\n", sup.c, sup.x, sup.y);
    	}
    	}
    }while(pguardia.x!=pladro.x || pguardia.y!=pladro.y);
    }
    
    void cguardia(int guardia, int  ladro){//riceva da un clinet e invia dati all'altro
    struct pos sup;
    do{
    	if(pguardia.x!=pladro.x || pguardia.y!=pladro.y){
    	if(recv(guardia, &pguardia, sizeof(pguardia),0) > 0){
    		printf("ricevuto guardia\n");
    		printf("%c %d %d \n", pguardia.c, pguardia.x, pguardia.y);
    	}
    	sup = pguardia;
    	if(send(ladro, &sup, sizeof(sup),0) > 0){
    		printf("inviato ladro\n");
    		printf("%c %d %d \n\n", sup.c, sup.x, sup.y);
    	}
    	}
    }while(pguardia.x!=pladro.x || pguardia.y!=pladro.y);
    }
    
    
    void startgame (int pl1, int pl2){ //fa iniziare una partita
    	int  pid_game, r, guardia, ladro;
    	pladro.x=MAXX;
    	pladro.y=MAXY;
    	pladro.c='$';
    	pguardia.x=0;
    	pguardia.y=0;
    	pguardia.c='#';
    	r=random();
    	if(r%2 == 0){
    		guardia=pl1;
    		ladro=pl2;
    	}else{
    		guardia=pl2;
    		ladro=pl1;
    	}	
    	send(guardia, "Sei la guardia\n", 15, 0);
    	send(ladro, "Sei il ladro\n", 13, 0);
    	usleep(100000);
    	send(guardia, "#",1,0); 
    	send(ladro, "$",1,0);
    	usleep(100000);
    		switch (pid_game = fork()){
    			case -1:
    				perror("Errore nell'esecuzione della fork (ladro)");
    				exit(4);
    			case 0: cladro(guardia, ladro);
    			default: cguardia(guardia, ladro);			
    		}
    	kill(pid_game, 1);		
    }
    
    
    int main (int argc, char **argv) {
    	int sock, fdpl1, fdpl2, pid_gioco;
    	int waiting=0;
    	char prev='l';
    	struct sockaddr_in server;
    	if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    		perror("chiamata alla system call socket fallita");
    		exit(1);
    	}
    	server.sin_family = AF_INET;
    	server.sin_addr.s_addr = htonl(INADDR_ANY);
    	server.sin_port = htons(SERVER_PORT);
    	if (bind(sock, (struct sockaddr *)&server, sizeof server) == -1) {
    		perror("chiamata alla system call bind fallita");
    		exit(2);
    	}
    	listen(sock, MAX_CONN);
    	/* gestione delle connessioni dei clienti */
    	printf("Server avviato correttamente\n");
    	while (1) {
    		if (prev == 'l'){
    			if ((fdpl1 = accept(sock, NULL, 0)) < 0) { 
    				perror("accepting connection");
    				exit(3);
    			}
    			prev = 'g';
    		}
    		else{
    			if ((fdpl2 = accept(sock, NULL, 0)) < 0) { 
    				perror("accepting connection");
    				exit(3);
    			}
    			prev = 'l';
    		}		
    		waiting++;
    		printf("ricevuta una connessione\n");
    		if (waiting >1){
    			waiting = waiting - 2;
    			switch (pid_gioco = fork()){
    				case -1:
    					perror("Errore nell'esecuzione della fork (startgame)");
    					exit(4);
    				case 0:
    					printf("avvio startgame\n");
    					startgame(fdpl1, fdpl2);			
    			}
    	
    		} else 
    			send(fdpl1, "Ricerca giocatori in corso...\n", 31, 0);			
    	}
    	printf("Shutdown server\n");
    	close (sock);
    }
    Mentre questo è il server con il timer:
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netdb.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <ctype.h>
    #include <sys/times.h>
    #include <sys/wait.h>
    
    #define SERVER_PORT 1025
    #define MAX_CONN 10
    #define MAXX 50
    #define MAXY 18
    
    
    struct pos {      	//rappresentazione delle coordinate del personaggio
    	char c;
    	int x;
    	int y;
    };
    
    struct pos pguardia, pladro;
    
    
    void cladro(int guardia, int ladro){//riceva da un clinet e invia dati all'altro
    struct pos sup;
    do{
    	if(pguardia.x!=pladro.x || pguardia.y!=pladro.y){
    	if(recv(ladro, &pladro, sizeof(pladro),0) > 0){
    		printf("ricevuto ladro\n");
    		printf("%c %d %d \n", pladro.c, pladro.x, pladro.y);
    	}
    	sup = pladro;
    	if(send(guardia, &sup, sizeof(sup),0) > 0){
    		printf("inviato guardia\n");
    		printf("%c %d %d \n\n", sup.c, sup.x, sup.y);
    	}
    	}
    }while(pguardia.x!=pladro.x || pguardia.y!=pladro.y);
    }
    
    void cguardia(int guardia, int  ladro){//riceva da un clinet e invia dati all'altro
    struct pos sup;
    do{
    	if(pguardia.x!=pladro.x || pguardia.y!=pladro.y){
    	if(recv(guardia, &pguardia, sizeof(pguardia),0) > 0){
    		printf("ricevuto guardia\n");
    		printf("%c %d %d \n", pguardia.c, pguardia.x, pguardia.y);
    	}
    	sup = pguardia;
    	if(send(ladro, &sup, sizeof(sup),0) > 0){
    		printf("inviato ladro\n");
    		printf("%c %d %d \n\n", sup.c, sup.x, sup.y);
    	}
    	}
    }while(pguardia.x!=pladro.x || pguardia.y!=pladro.y);
    }
    
    
    void startgame (int pl1, int pl2, int timer){ //fa iniziare una partita
    	int  pid_ladro, pid_guardia, pid_timer, status;
    	int r, guardia, ladro;
    	pladro.x=MAXX;
    	pladro.y=MAXY;
    	pladro.c='$';
    	pguardia.x=0;
    	pguardia.y=0;
    	pguardia.c='#';
    	r=random();
    	if(r%2 == 0){
    		guardia=pl1;
    		ladro=pl2;
    	}else{
    		guardia=pl2;
    		ladro=pl1;
    	}	
    	send(guardia, "Sei la guardia\n", 15, 0);
    	send(ladro, "Sei il ladro\n", 13, 0);
    	usleep(100000);
    	send(guardia, "#",1,0); 
    	send(ladro, "$",1,0);
    		switch (pid_ladro = fork()){
    			case -1:
    				perror("Errore nell'esecuzione della fork (ladro)");
    				exit(4);
    			case 0: cladro(guardia, ladro);
    			default:
    				switch (pid_guardia = fork()){
    					case -1:
    						perror("Errore nell'esecuzione della fork (guardia)");
    						exit(4);
    					case 0: 
    						cguardia(guardia, ladro);
    					default:
    						switch(pid_timer = fork()){
    							case -1:
    								perror("Errore nell'esecuzione della fork (timer)");
    								exit(4);
    							case 0:
    								sleep(timer);
    							default: 
    								wait(&status);
    								close(guardia);
    								close(ladro);					
    						}
    						
    				}			
    		}		
    }
    
    
    int main (int argc, char **argv) {
    	int sock, fdpl1, fdpl2, pid_gioco;
    	int waiting=0, timer;
    	char prev='l';
    	struct sockaddr_in server;
    	if (argc > 1)
    		timer = atoi(argv[1]);		
    	else {
    		printf("Non hai inserito la durata massima della partita!\n");
    		return 0;	
    	}
    	if (timer < 1){
    		 printf("La durata massima della partita inserita non è valida!\n");
    		 return 0;
    	}
    	if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    		perror("chiamata alla system call socket fallita");
    		exit(1);
    	}
    	server.sin_family = AF_INET;
    	server.sin_addr.s_addr = htonl(INADDR_ANY);
    	server.sin_port = htons(SERVER_PORT);
    	if (bind(sock, (struct sockaddr *)&server, sizeof server) == -1) {
    		perror("chiamata alla system call bind fallita");
    		exit(2);
    	}
    	listen(sock, MAX_CONN);
    	/* gestione delle connessioni dei clienti */
    	printf("Server avviato correttamente\n");
    	while (1) {
    		if (prev == 'l'){
    			if ((fdpl1 = accept(sock, NULL, 0)) < 0) { 
    				perror("accepting connection");
    				exit(3);
    			}
    			prev = 'g';
    		}
    		else{
    			if ((fdpl2 = accept(sock, NULL, 0)) < 0) { 
    				perror("accepting connection");
    				exit(3);
    			}
    			prev = 'l';
    		}		
    		waiting++;
    		printf("ricevuta una connessione\n");
    		if (waiting >1){
    			waiting = waiting - 2;
    			switch (pid_gioco = fork()){
    				case -1:
    					perror("Errore nell'esecuzione della fork (startgame)");
    					exit(4);
    				case 0:
    					printf("avvio startgame\n");
    					startgame(fdpl1, fdpl2, timer);			
    			}
    	
    		} else 
    			send(fdpl1, "Ricerca giocatori in corso...\n", 31, 0);			
    	}
    	printf("Shutdown server\n");
    	close (sock);
    }
  • Re: Guardie e Ladri client/server

    La partita però non termina allo scadere del timer ma solo quando la guarda "prende" il ladro. In più, il server non crea più nuove partite se arrivano altre connessioni (mentre nella versione senza timer lo faceva senza problemi).
    Se la connessione viene aperta dal padre e vuoi tenerla aperta allora potresti attendere con WAIT il processo di TIMER e fare SIGTERM sui processi GUARDIA e LADRO. Nel giro di WAIT puoi usare la macro WTERMSIG per riconoscere i processi ammazzati
    
    ...
     for (i=0;i<numero dei processi;i++)
      {
        pid=wait (&status);
        
        if (WIFEXITED(status))
        {
          // Sono uscito regolarmente da un figlio
          if (pid == pid timer)
          {
            printf ("TIMEOUT!\n");
            kill(PID GUARDIA,SIGTERM);
            kill(PID LADRO,SIGTERM);
          }
        }
        if (WTERMSIG(status))
          // Sono un processo morto ammazzato da mio padre !!! 
      }
    ...
    
  • Re: Guardie e Ladri client/server

    Ce l'ho fatta! Grazie mille, spiegazione a dir poco illuminante!
  • Re: Guardie e Ladri client/server

Devi accedere o registrarti per scrivere nel forum
22 risposte