Laura Esposito  
              Matricola : 565379
              Login     : le565379
	      

Vincenza Zermo
              Matricola : 563237
	      Login     : vz563237


===================

Modalita' d'uso
===================



ENTE TURISTICO   

Sorgente  : ente.c
Eseguibile: ./ente
Parametri : [porta]

ALBERGO 

Sorgente  : albergo.c
Eseguibile: ./albergo
Parametri : <indirizzo IP ente> [porta ente] [porta albergo]
		 

TURISTA  

Sorgente  : turista.c
Eseguibile: ./turista
Parametri : <indirizzo IP ente> [porta ente]



		 
=====================

Scelte di Progetto
=====================




STRUTTURE DATI E VARIABILI USATE 
---------------------------------

Nell'ente, nel turista e nell'albergo e' possibile trovare le seguenti variabili e strutture dati:

/* messaggi di Input e Output nelle socket e le stringhe d'appoggio */
  char In[MES]; 
  char Out[MES]; 
  char aus[MES];
  char aus1[MES]; 
  char aus2[MES]; 
  char appoggio[MES];

/* nome dell'albergo */
  char nome[NOME];   

  
/* indirizzo IP dell'albergo e dell'ente */ 
  char IP_hotel[IND_IP];
  char IP_ente[IND_IP];

/* lunghezza dell'indirizzo IP del client */  
  int lung;
  int lung_Tur;


/* strutture dati di tipo sockaddr_in dove sono memorizzati i dati della connessione */
/* come l'indirizzo IP, la famiglia degli indirizzi IP e la porta del protocollo usato (TCP/IP) */
  struct sockaddr_in cliente;
  struct sockaddr_in ind_ente;
  struct sockaddr_in ind_alb;
  struct sockaddr_in ind_tur;
  struct sockaddr_in *struc_aus;
   
/* puntatori alla struttura dati dell'albergo */
  struct albergo *primo_Alb;
  struct albergo *hotel;
  struct albergo *hotel_aus
  struct albergo *punta;
  struct albergo *head;
  

/*codice dell' albergo*/
  int codAlb; 
  
/* tabelle di descrittori di socket */
  fd_set rfds;
  fd_set afds;

/*descrittori di socket */  
int fd, nfds; 


/* risultato della read */
  int err;  
  
/* socket attiva del server e passiva del client*/
  int asock;
  int psock;
  int sock;
  int sock_Alb;
  int sock_Ente;
  int sock_Tur;
  unsigned shor int sock;
  
/*numero di porta a cui e' associata la socket */
  int porta; 
  int porta_Alb; 
  int porta_Ente;
  

/* numero degli alberghi nella lista */
  int N_Alberghi;

/* massimo numero di socket aperte e con connessione attiva */
  int Num_sock[MAX_SOCK];

/*variabili per la gestione della prenotazione dei posti */
  int nho, ris, as, posti, num; 
  int PostiPren;
  int NumPren;
  
/* variabile per definire lo stato dell'albergo */
   char stato;  



Nella libreria vi sono definite le seguenti costanti e variabili :

/* numero massimo di descrittori di socket disponibili alla connessione */
  MAX_SOCK FOPEN_MAX;

/* grandezza massima delle costanti */
  Ndisponibili 10;
  MES 200;
  NOME 50;
  IND_IP 40;




/* varabili per la gestione dell'errore */
  extern int errno; 
  extern char *sys_errlist[];


/* struttura dati dell'albergo */
  struct albergo {
     int codice;
     char nome[30];
     int posti;
     char stato;
     char indIP[40];
     unsigned short int porta;
     struct albergo *next;
   };




ENTE TURISTICO
------------------


Nell'ente tursitico (server dell'architettura) vengono richiamate le seguenti procedure:

int SocketPassiva(unsigned short porta);
void Gestisci(int psock);
int NuovoClient(int asock);
int Client(int asock);



Procedura SocketPassiva():
Viene creata una socket per accettare le connessioni dei client. Tale socket e' in 
dominio internet e di tipo bytestream poiche' utilizza il protocollo TCP/IP
I dati relativi alla connessione sono memorizzati in una struttura di tipo sockaddr_in
e associati alla porta attraverso l'istruzione bind().
A questo punto la socket, attraverso l'istruzione listen() viene abilitata alla ricezione
di richieste di connessione.


Procedura Gestisci():
La richiesta di connessione da parte di un client viene gestita attaverso queste
operazioni:
- Viene assegnato a nfds in numero massimo di fd aperti contemporaneamente.
- nel ciclo while(1) rfds(struttura dati che contiene i file descriptor,copia di afds)
  viene passata alla select() e viene modificata.
- la select() attiva l'attesa su piu' socket contemporaneamente.
- le richieste di connessione vengono accettate attraverso l'istruzione accept() che
  toglie un elemento dalla lista delle richieste e vi associa una socket.
- tale socket viene utilizzata per l'invio e la ricezione dei dati.
- se non vi sono richieste di connessione la chiamata accept() risultera' essere bloccante
  interrompendo il ciclo esecutivo del server. 


Procedura NuovoClient():
Tale procedura viene usata per scrivere i messaggi sulla socket dedicata alla connessione.
Si gestiscono le scelte del client che si e' connesso:
- turista: richiede l'invio della lista degli alberghi connessi;
- albergo: viene aperto o chiuso in base alla richiesta e se lo stato e' aperto spedisco
           i dati al turista.


Procedura Client():
Viene inizializzata la connessione con il client memorizzandone l'indirizzo IP e la porta
tramite l'uso della getpeername(). Si estrae il codice del client e lo si controlla :
- se e' un turista si comunica che si e' connesso un nuovo turista spedendo un ack;
- se e' un albergo se ne memorizza il codice, il nome, il numero di posti, l'indirizzo IP
  e la porta nella rispettiva struttura.
  Si inserisce nella coda della lista il nuovo albergo e lo si comunica a video.
Si memorizza infine nell'array, la corrispondenza tra socket e albergo.



 
 
TURISTA
------------

Nel turista (client dell'architettura) avvengono le seguenti fasi :

- inizialmente il turista richiede la  connessione all'ente controllando se e' esatta
  l'apertura della socket, si memorizzano i dati in una struttura di tipo sockaddr_in e
  attraverso la connect() si apre la connessione all'ente.

- successivamente si richiede la lista degli alberghi connessi e viene gestita l'attesa
  dei messaggi contenenti i dati degli alberghi.
  Nel ciclo while(1) vengono eseguite le seguenti operazioni:
  - si memorizza il nome dell'albergo, il numero di posti, l'indirizzo IP e la porta
    nella struttura albergo 
  - si inserisce il nuovo albergo in coda alla lista degli alberghi  
  - si chiude la connessione con l'ente
  - si controlla che il numero di alberghi ricevuti sia maggiore di zero e attraverso la
    funzione rand() si esegue la scelta  scandendo la lista
  - si copiano le informazioni dell'albergo scelto in apposite variabili
  - si elimina la lista degli alberghi
  - si apre la connessione con l'albergo scelto memorizzando i dati della connessione in
    una struttura di tipo sockaddr_in
  - vengono scelti il numero di posti da prenotare e se ne spedisce la richiesta
  - viene controllato l'esito della prenotazione
  - si chiude la connessione con l'albergo
  - si blocca il processo per 4 secondi




ALBERGO
-------------

Viene creato, all'interno del client albergo, un server per il turista con  numero di 
porta prescelta creando e inizializzando  una socket attiva per il turista e aprendo
la connessione con l'ente.
Nel server-client albergo vengono richiamate le seguenti procedure :

int socketEnte(char *IP_Ente, int porta_Ente, int porta_Alb);
int serverSock(int porta_Alb);
int Gestisci(int sock_Alb, int sock_Ente);
void NomePosti_Alb(void);
void Menu(int PostiPren, char stato);



Procedura socketEnte():
Viene inoltrata la richiesta di connessione all'ente memorizzando i dati della connessione
in una struttura di tipo sockadd_in. L'Id ricevuto dall'ente viene memorizzato e controllato
attendendo poi l'ACK dall'ente, infine viene restituito il numero identificativo della socket. 


Procedura serverSock():
Viene creata una socket in dominio internet e di tipo bytestream(TCP) per accettare le 
connessioni dei turisti. Vengono memorizzati  i dati della connessione in una struttura di
tipo sockaddr_in e la socket viene abilitata alla ricezione delle connessioni.


Procedura Gestisci():
Nella procedura si ha l'inizio del ciclo d'attesa del server albergo :
la select() attiva la lettura su piu' socket contemporaneamente attendendo le richieste
di connesione su esse.
Viene eseguito un controllo pe verificare la richiesta di connessione del turista, accettandola
e spedendo l'ACK di avvennuta connessione.
Il turista spedisce un messaggio di prenotazione che permette all'albergo di verificare il suo stato :
- se l'albergo ha stato "aperto" allora viene accettata la prenotazione, estraendo il numero di posti
  prenotati e controllando se puo' esere accettata come tipo di prenotazione; se i posti disponibili 
  sono insufficienti viene comunicato che l'albergo e' al completo, se invece sono sufficienti per la 
  prenotazione si spedisce un ACK;
- se l'albergo e' chiuso non si possono accettare prenotazioni e viene spedito un NACK chiudendo la 
  connessione con il turista.
Vengono anche gestite le richieste dell'utente da tastiera, i cui testi accettati sono :
"m" o "M" per visualizzare il menu dei comandi;
"a" o "A" per cambiare lo stato dell'albergo in aperto:
          viene spedito  il msg all'ente attendendo l'ACK di accettazione all'apertura;
"c" o "C" per cambiare lo stato dell'albergo in chiuso:
          l'albergo e' di default chiuso quindi viene controllato inizialmente se lo stato e' aperto
	  e lo si cambia attendendo poi un ACK dalle'nte di avvenuta chiusura
"p" o "P" per la stampa delle prenotazioni ricevute;
"z" o "Z" per azzerare il contatore delle prenotazioni
E infine c'e' il controllo sulla chiusura della socket da parte dell'ente, per chiudere ordinatamente.



Procedura NomePosti_Alb():
Viene scelto il nome e il numero di posti dell'albergo inizializzando la sequenza casuale e scegliendo 
un numero, poi si memorizzano nella struttura dell'albergo.


Procedura Menu():
Viene stampato a video il menu dei comandi per l'utente.






LIBRERIA
-------------


La libreria del progetto contiene le seguenti procedure :


int Errore(char *prompt, int err, char *errcode);
int estrai(char *mes[], char *aus[]);
struct albergo* ricercaAl(int codAlb);
int Send(int sock, char *s);
int eliminaAl(struct albergo *primo_Alb);
int eliminaLAlberghi(void);



Procedura Errore():
viene gestito l'evntuale errore stampandone a video la tipologia e il codice

Procedura estrai():
viene estratto il primo campo dal messaggio passato

Procedura ricercaAl():
viene ricercato l'albergo (scandendo la lista) passando il codice e 
viene restituito il puntatore alla struttura dati relativa all'albergo ricercato

Procedura Send():
viene scritto il messaggio da passare alla socket 

Procedura eliminaAl():
viene eliminato l'albergo passto dalla lista degli alberghi scorrendo tutta la lista

Procedura eliminaLAlberghi():
elimina tutta la lista degli alberghi




============================

Organizzazione del programma
============================

Per poter far funzionare il progetto bisogna seguire le seguenti regole :

1 - Eseguire per primo l'ente poiche' e' server sia del turista che dell'albergo,
    passandogli il numero di porta su cui sta girando;

2 - Eseguire a scelta o il turista(client) o l'albergo (server-client: server per
    il turista, client per l'ente);
    
    2a - Turista: gli passo l'indirizzo Ip e la porta dell'ente;
    2b - Albergo: gli passo l'indirizzo Ip,la porta dell'ente e la porta dell'albergo
                  stesso
		  
		  
		  

============================

Modalita' di compilazione
============================


Il compilatore usato e' gcc nella seguente modalita' :

gcc -o ente ente.c
gcc -o turista turista.c
gcc -o albergo albergo.c
    

