#include <stdio.h>
#include <sys/socket.h>      /* Libreria per la accept */
#include <netinet/in.h>        /* Libreria per sockaddr_in */
#include <sys/types.h>		 /* standard system types	*/
#include <netdb.h>		        /* host to IP resolution 	*/

#define PORT 10000           /* Port richiesto dall'esercizio */
#define  WELLCOME 	"Benvenuti."

int crea_socket (int port)
{
  int socketsd;        /* Descrittore del socket locale */
  struct sockaddr_in local_address;

  /* Creo il descrittore del socket locale */ 
  socketsd = socket (PF_INET, SOCK_STREAM, 0);
  if (socketsd < 0)
    return -1;

    /* inizializzo la struttura dell'indirizzo internet del server */
    /* la funzione utilizzata copia 0 nei primi sizeof(local_address) byte dell'oggetto puntato
       da &local_address, operando in pratica un azzeramento della struttura. */
    memset(&local_address, 0, sizeof(local_address));
        
  /* Creo l'indirizzo Internet locale */
  local_address.sin_family = AF_INET;   /* Viene usato la famiglia di Protocollo Internet */
  local_address.sin_addr.s_addr = htonl (INADDR_ANY); /* accetta connessioni da qualunque indiirizzo IP */
  local_address.sin_port = htons (port); /* ordinamento dei Byte da Host a Rete */

  /* La chiamata bind lega l' indirizzo locale alla connessione  */
  if (bind (socketsd, (struct sockaddr *) &local_address, sizeof (local_address)) < 0)
    return -1;

  /* Stabiliamo che il numero massimo di connessioni da lasciare in coda è 1 */
  if (listen (socketsd, 1) < 0)
    return -1;
  return socketsd;
}

int main ()
{
  int socket_query, socket_service;
  struct sockaddr_in client_address;
  int 	size_client_address; /* dimensioni della struttura client_address */

  int l, caratteri;

  /* Creo il descrittore del socket locale usando il port 10000*/
  socket_query = crea_socket (PORT);
  if (socket_query < 0)
    {
      perror ("ERRORE: chiamata alla system call socket fallita");
      return -1;
    }
  puts ("Chiamata alla system call socket OK!");

    size_client_address = sizeof(client_address);
    
  /* Il server resta in ascolto con questo loop indefinito, in attesa di una richiesta di connessione */
  while ( 1 ) {

    /* Attende una richiesta da cliente */
    socket_service = accept ( socket_query, (struct sockaddr *) &client_address,  &size_client_address);
    if (socket_service < 0)
      {
	perror ("ERRORE: accepting connection");
	return -1;
      }
	write(socket_service, WELLCOME, sizeof(WELLCOME));
	
	sleep(3);
	
    /* Chiusura del socket */
    close (socket_service);
  }
}