home *** CD-ROM | disk | FTP | other *** search
/ ftp.disi.unige.it / 2015-02-11.ftp.disi.unige.it.tar / ftp.disi.unige.it / pub / .person / GianuzziV / SO1 / echo_server_thread.c < prev    next >
C/C++ Source or Header  |  2005-04-03  |  4KB  |  124 lines

  1. /**********************************************************************************
  2. * Programma:      echo_server_thread                                              *
  3. *                                                                                 *
  4. * finalita':      Fa l'echo di un messaggio ricevuto, generando un thread         *
  5. *                 ad ogni richiesta di connessione                                *
  6. *                 E' un'alternativa a echo_server e lavora sulla porta 3123       * 
  7. *                 Si esegue in background (&).                                    *
  8. *                 Ricordarsi di killarlo alla fine della prova.                   *
  9. *                                                                                 *
  10. * Sintassi:       echo_server_thread                                              *
  11. *                 Il port number e' SERVER                                        *
  12. *                 Il client e' echo_client.c, il protocollo e' TCP.               *
  13. *                                                                                 *
  14. *   gcc -D_REENTRANT -o echo_server_thread echo_server_thread.c -lpthread         *
  15. *                                                                                 *
  16. ***********************************************************************************/
  17.  
  18. #include <errno.h>
  19. #include <stdio.h>
  20. #include <sys/types.h>
  21. #include <sys/socket.h>
  22. #include <netinet/in.h>
  23. #include <netdb.h>
  24. #include <pthread.h>
  25.  
  26. #define  BACKLOG         5      /* n. max di richieste in coda */
  27. #define  MAXHOSTNAME    32      /* lunghezza massima nome host */
  28. #define  SERVER       3123      /* porta del server */
  29.  
  30. char    zero[20];
  31. pthread_mutex_t  lock;
  32. int count=0;
  33. char    *myname;              /* nome di questo eseguibile */
  34.  
  35. echo(int sock)
  36. {  char    buf[BUFSIZ], ret[BUFSIZ];
  37.    int     i;
  38.  
  39.    /* legge una richiesta */
  40.    if ((i=read(sock, buf, BUFSIZ))<= 0)
  41.        strcpy(ret, "non ho letto niente \n");
  42.    else {
  43.           buf[i]=' ';           /* terminatore nullo */
  44.           sprintf(ret, "ho letto %s \n", buf);
  45.         }
  46.    /* invia la risposta */
  47.    write(sock, ret, strlen(ret));
  48.    strcpy(ret, zero);
  49.  
  50.    pthread_mutex_lock(&lock);
  51.    count++;
  52.    pthread_mutex_unlock (&lock);  
  53.  
  54.    printf("%s: count=%d\n", myname, count);
  55.    
  56.    close(sock);
  57.    return;
  58. }
  59.  
  60. main (int argc, char **argv)
  61. { int  sfd, tfd;                /* socket descr. */
  62.   int  i,err;                   
  63.   struct  sockaddr_in  sa, isa; /* indirizzi Internet */
  64.   struct  hostent  *hp;         /* risultato host name lookup */
  65.   struct  servent  *sp;         /* risultato service lookup */
  66.   char    localhost[MAXHOSTNAME+1]; /* local host name come stringa */
  67.   pthread_t    th;
  68.   int  rc;
  69.   
  70.   pthread_mutex_init(&lock, NULL);
  71.    
  72.   myname=argv[0];
  73.  
  74.   for (i=1; i<21; i++) {zero[i]='\0';}
  75.   /* chiede l'indirizzo del local host */
  76.   gethostname(localhost,MAXHOSTNAME);
  77.   if ((hp=gethostbyname(localhost))==NULL)  {
  78.      fprintf(stderr, "%s:  errore local host \n", myname);
  79.      exit(1);
  80.     }
  81.  
  82.   /* inserisce il socket number dentro la struttura del socket */
  83.   sa.sin_port=htons((short int) SERVER);
  84.  
  85.   /* costruisce la struttura che contiene l'indirizzo del local host */ 
  86.   bcopy((char *) hp->h_addr, (char *) &sa.sin_addr, hp->h_length);
  87.   sa.sin_family=hp->h_addrtype;
  88.  
  89.   /* richiede un descrittore di socket */
  90.   if (( sfd=socket(hp->h_addrtype, SOCK_STREAM, 0))<0 )   {
  91.      fprintf(stderr, "%s:  errore apertura socket \n", myname);
  92.      exit;
  93.   }
  94.   /* fa il bind alla service port */
  95.   if ((err=bind(sfd, (struct sockaddr *) &sa, sizeof sa))<0)   {
  96.      fprintf (stderr, "%s:  errore %d   \n", myname, errno);
  97.      fprintf (stderr, "%s:  bind rifiutato, errore %d   porta %d\n", 
  98.                myname, err, ntohs(sa.sin_port));
  99.      exit(1);
  100.      }
  101.  
  102.   /* massimo numero di connessioni accettate */
  103.   listen(sfd, BACKLOG);
  104.  
  105.   /* loop infinita di attesa richieste */
  106.   for (;;)   {
  107.       i=sizeof isa;      
  108.       if (( tfd=accept(sfd, (struct sockaddr *) &isa, &i))<0)   {
  109.           printf("%s:  errore accept \n", myname);
  110.           exit(1);
  111.           }
  112.  
  113.       rc = pthread_create(&th, NULL, (void *) echo, (void *) tfd);
  114.       if (rc) {
  115.           fprintf(stderr, "%s: errore %d  \n", myname, errno);
  116.           fprintf (stderr, "%s:  creaziuone thread rifiutato, errore %d \n", 
  117.                myname, rc);
  118.           exit (1);
  119.           }
  120.       }
  121. }
  122.  
  123.  
  124.