###############################################################################
Programma della conferenza distribuita
Copyright (C) 19aa
Autori: Andrea Lanzi, Giampaolo Fresi Roglia
Questo programma e' software libero; e' lecito ridistribuirlo e/o
modificarlo secondo i termini della Licenza Pubblica Generica GNU
come pubblicata dalla Free Software Foundation; o la versione 2
della licenza o (a scelta) una versione successiva.
Questo programma e' distribuito nella speranza che sia utile, ma
SENZA ALCUNA GARANZIA; senza neppure la garanzia implicita di
COMMERCIABILITA' o di APPLICABILITA' PER UN PARTICOLARE SCOPO. Si
veda la Licenza Pubblica Generica GNU per avere maggiori dettagli.
Ognuno dovrebbe avere ricevuto una copia della Licenza Pubblica
Generica GNU insieme a questo programma; in caso contrario, la si
puo' ottenere dalla Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, Stati Uniti.
Gli autori possono essere contattati ai seguenti indirizzi:
Andrea Lanzi : shadow.net@tiscalinet.it
Giampaolo Fresi Roglia : gian_fresi@iol.it
###############################################################################
#include "client_subs.h"
#include "messages.h"
/******************************************************************************/
// IL SEGNALE SIGPIPE VIENE IGNORATO
void ignora()
{
signal(SIGPIPE, ignora);
}
/******************************************************************************/
int main (int argc, char *argv[])
{
int iscr=0, iscr_p=0, fine=0, ris, n;
#ifdef UNBUFFERED
int invio = 0;
#endif
int coord_sock, serv_sock, clilen;
int newsockfd=0;
char scel, scel2;
char buf[MAX_DIM];
char *str_ind;
unsigned long indirizzo;
int porta;
struct sockaddr_in cli_addr;
char *SERV_HOST_ADDR;
int SERV_TCP_PORT;
int ADD_GUEST = _ADD_GUEST;
int TALK = _TALK;
int ACK = _ACK;
fd_set afds,rfds;
signal(SIGPIPE, ignora);
// MENU DEI COMANDI DELL'UTENTE
menu();
if (argc!=3){
printf("\nLanciare client con indirizzo del server e numero di porta\n ");
exit(0) ;
}
//ASSEGNAZIONE DELL''INDIRIZZO E PORTA DEL SERVER
SERV_HOST_ADDR=argv[1];
SERV_TCP_PORT=atoi(argv[2]);
FD_ZERO(&afds);
FD_SET (0, &afds);
while (! fine)
{
bcopy( (char*) &afds, (char*) &rfds, sizeof(rfds) ) ;
if ((select(FOPEN_MAX, &rfds, NULL, NULL, NULL)) < 0)
{
perror ("select");
exit(0);
}
// GESTIONE DELLO STANDARD INPUT DA PARTE DELLA SELECT
if (FD_ISSET(0, &rfds))
{
read(0, &scel, sizeof(scel));
scel2 = scel;
while(scel2 != 10)
read(0, &scel2, sizeof(scel2));
switch (scel)
{
// ISCRIZIONE DEL CLIENT
case '1':
if (! iscr)
{
if ((iscrizione( SERV_HOST_ADDR, SERV_TCP_PORT, &coord_sock,
&serv_sock)) < 0)
menu();
else
{
iscr=1;
FD_SET(coord_sock, &afds); //SOCKET CON IL COORDINATORE
FD_SET(serv_sock, &afds); //SOCKET IN ASCOLTO
}
}
break;
//ISCRIZIONE A PARLARE
case '2':
if (iscr && (! iscr_p))
{
if ( iscr_parl(coord_sock) < 0 )
perror("iscrizione a parlare");
else iscr_p=1;
}
break;
//RINUNCIA A PARLARE
case '3':
if (iscr_p)
{
if ((rinuncia(coord_sock)) < 0)
exit(0);
else iscr_p=0;
}
break;
// DISCONNESSIONE DEL CLIENT
case '4':
if (iscr)
{
if ((disconnetti(coord_sock)) < 0)
{
perror("disconnetti");
exit(0);
}
else
{
iscr=0;
FD_CLR(serv_sock, &afds);
close(serv_sock);
FD_CLR(coord_sock, &afds);
close(coord_sock);
}//fineif
}
break;
// USCITA DAL MENU
case '5':
exit(0);
default:
menu();
}//fine switch
}
//GESTIONE DELLA SOCKET CON L'ORATORE
else if(FD_ISSET(newsockfd, &rfds))
{
n=read(newsockfd,buf,MAX_DIM);
buf[n]='\0' ;
// GESTIONE DI FINE MESSAGGIO
#ifdef UNBUFFERED
if (n>0)
{
if(buf[n-1]!=10)
invio = 0;
else invio++;
}
if ((n<=0)||(invio==2))
#else
if((strcmp(buf,"\n")==0)||(n<=0))
#endif
{
FD_CLR(newsockfd, &afds);
close( newsockfd );
printf("Fine messaggio\n");
newsockfd = 0;
}
write(1,buf,n);
}
//GESTIONE DELLA SOCKET DEL COORDINATORE CON LA SELECT
else if (FD_ISSET(coord_sock, &rfds))
{
// SE LA LETTURA DA ERRORI LA CONNESSIONE CON IL COORDINATORE
// E' CADUTA
if(read(coord_sock, &ris, sizeof(ris))<=0)
{
printf("perso contatto coordinatore\nesco\n");
perror("read");
exit(-1);
}
// SE INVECE SI E' CONNESSO O DISCONNESSO UN PARTECIPANTE
// VIENE NOTIFICATO
if (iscr_p==0)
{
read(coord_sock, &indirizzo, sizeof(indirizzo));
read(coord_sock, &porta, sizeof(porta));
bzero((char *) &cli_addr, sizeof(cli_addr));
cli_addr.sin_addr.s_addr = indirizzo;
str_ind=inet_ntoa(cli_addr.sin_addr);
if(ris==ADD_GUEST)
printf("Connessione di: %s:%d\n",str_ind, porta);
else
printf("Disconnessione di: %s:%d\n",str_ind, porta);
}
else
{
// IL COORDINATORE HA DATO LA PAROLA AL CLIENT
if (ris == TALK)
{
if (newsockfd != 0)
{
FD_CLR(newsockfd, &afds);
close(newsockfd);
printf("Fine messaggio\n");
newsockfd = 0;
}
printf("\nRicevo il diritto di parola dal coordinatore\n");
write(coord_sock, &ACK, sizeof(ACK));
printf("Invio ACK al coordinatore\n");
if ((gest_conv(coord_sock)) < 0)
{
perror("gest_conv");
exit(0);
}
iscr_p=0;
}
else
// VIENE NOTIFICATO AGGIUNTA O DISCONNESSIONE DI
// UN NUOVO PARTECIPANTE
{
read(coord_sock, &indirizzo, sizeof(indirizzo));
read(coord_sock, &porta, sizeof(porta));
bzero((char *) &cli_addr, sizeof(cli_addr));
cli_addr.sin_addr.s_addr = indirizzo;
str_ind=inet_ntoa(cli_addr.sin_addr);
if(ris==ADD_GUEST)
printf("Connessione di: %s:%d\n",str_ind, porta);
else
printf("Disconnessione di: %s:%d\n",str_ind, porta);
}
}
}
//GESTIONE DELLA SOCKET PASSIVA IN ASCOLTO VERSO L''ORATORE
else if(FD_ISSET(serv_sock, &rfds))
{
//CREAZIONE DELLA SOCKET CON L''ORATORE
clilen = sizeof( cli_addr ) ;
newsockfd = accept(serv_sock, (struct sockaddr *) &cli_addr, &clilen ) ;
printf("\nAccetto la connessione dall'oratore corrente\n");
FD_SET(newsockfd, &afds);
}
}
exit(0);
}
/*********************************************************************************************/