/* Programma:     servente_i_msg
*  Autore:        FF
*  Data:          06/02/2006
*  Descr.:        Esempio di servente iterativo TCP che accetta una connessione
*                 da un cliente e scambia messaggi con esso
*/
#include "utilsock.h"
/* utilsock.h contiene tutte le inclusioni delle altre librerie necessarie
*  e le funzioni di lettura e scrittura dal socket
*/
#define MAX        256
#define BACKLOG 20

int main(int argc, char *argv[])
{
    int sd,accsd,l;
    struct sockaddr_in serv_ind, cliente;
    char msg[MAX],indcli[128];
    int msglun=MAX,val=1;
    socklen_t lung;
    in_port_t porta;
    printf("\033[2J\033[H");
    // controlla argomenti
    if (argc !=2) {
        printf("\nErrore\n");
           printf("Si deve digitare: \n");
        printf("./servente_i_msg porta (>1023)\n");
        printf("Premere Invio\n");
        getchar();
        exit(-1);
    }
    // crea socket 
    if ( (sd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
        perror("Errore nella creazione del Socket");
        exit(-1);
    }
    // rende il socket riusabile
    setsockopt(sd,SOL_SOCKET,SO_REUSEADDR,&val,sizeof(val));
    // indirizzo ip
    memset((void *)&serv_ind, 0, sizeof(serv_ind)); // pulisce ind
    serv_ind.sin_family = AF_INET;                  // ind di tipo INET 
    porta=atoi(argv[1]);
    serv_ind.sin_port = htons(porta);               // scelgo porta non priv.
    serv_ind.sin_addr.s_addr = htonl(INADDR_ANY);   // connessioni da ogni ip
    // bind socket 
    if (bind(sd, (struct sockaddr *)&serv_ind, sizeof(serv_ind)) < 0) {
        perror("Errore nella bind");
        exit(-1);
    }
    // listen 
    if (listen(sd, BACKLOG) < 0 ) {
        perror("Errore nella listen");
        exit(-1);
    }
    printf("In ascolto sulla porta %d\n",porta);
    // accetta connessione
    if ( (accsd = accept(sd, (struct sockaddr *)&cliente, &lung)) <0 ) {
        perror("Errore nella accept");
        exit(-1);
    }
    inet_ntop(AF_INET, &cliente.sin_addr, indcli, sizeof(indcli));
    printf("Cliente %s connesso\n",indcli);
    printf("Per terminare digitare il messaggio: /ciao\n");
    do {
      printf("Messaggio da inviare: ");
      for(l=0;((msg[l]=getchar())!='\n' && l<MAX-1);l++);
      msg[l]='\0';     
      scrivisock(accsd,msg,l+1);
      printf("OK messaggio inviato\n");    
      printf("In attesa di messaggio\n\n");      
      if ( (read(accsd,msg,msglun))<=0 ) {
          perror("Errore nella read");
          exit(-1);
      }       
      printf("Messaggio ricevuto: %s\n",msg);
    }
    while(strcmp(msg,"/ciao")); // usare /ciao per finire
    close(accsd);
    close(sd);
exit(0);
}

