viernes, 10 de julio de 2015

Comer sockets

Del libro del Sr. Comer sobre Internetworking with TCP/IP se puede encontrar un ejemplo de la utilización de Sockets. También es válido para comunicación entre procesos IPC.
He aquí los dos archivos para el ejemplo:



 /*whoisclient.c -main */  
 #include <stdio.h>  
 #include <stdlib.h>  
 #include <string.h>  
 #include <sys/types.h>  
 #include <sys/socket.h>  
 #include <netinet/in.h>  
 #include <netdb.h>  
 /*_________________________________________________________________  
  * Program: whoisclient  
  *  
  *Purpose: UNIX application program thar becomes a client for the  
  *       Iternet "whois" services.  
  *  
  *Use:   whois hostname username  
  *  
  *__________________________________________________________________  
  */  
 main (argc,argv)  
 int argc;          /*standard UNIX argument declarations */  
 char *argv[];  
 {  
   int s;              /*socket descriptor           */  
   int len;               /*length of received data          */  
   struct sockaddr_in sa;     /*Internet socket addr, structure     */  
   struct hostent *hp;          /*result of host name lookup          */  
   struct servent *sp;          /*result of service lookup          */  
   char *myname;          /*pointer to name of this program     */  
   char *host;               /*pointer to mte host name          */  
   char *user;               /*ponter to mte user name          */  
   myname = argv[0];  
   char buf[BUFSIZ+1];  
   /*  
   * Check that there are two command line arguments  
   */  
 if(argc != 3){  
      fprintf(stderr,"Usage: %s host username\n", myname);  
      exit(1);  
 }   
 host = argv[1];  
 user = argv[2];  
 /*  
  * Look up the specified hostname  
  */  
 if((hp = gethostbyname(host)) == NULL) {  
      fprintf(stderr, "%s: %s: no such host?\n", myname, host);  
      exit(1);  
 }  
 /*  
  * Put host's addres and address type into socket structure  
  */  
 bcopy((char *)hp->h_addr, (char *)&sa.sin_addr, hp->h_length);  
 sa.sin_family = hp->h_addrtype;  
 /*  
  * Look up the socket number for the WHOIS service  
  */  
 if((sp = getservbyname("whois","tcp")) == NULL ){  
      fprintf(stderr,"%s: No whois service on this host\n", myname);  
      exit(1);  
 }  
 /*  
  * Put the whois socket number into the socket structure  
  */  
 sa.sin_port = sp->s_port;  
 /*  
  * Allocate an open socket  
  */  
 if ((s = socket(hp->h_addrtype, SOCK_STREAM,0)) < 0 ){  
      perror("socket");  
      exit(1);  
 }  
 /*  
  * Connect to the remote server ahora (struct sockaddr*)  antes &sa  
  */  
 if(connect(s, (struct sockaddr*)&sa , sizeof(sa)) < 0){  
      perror("connect");  
      exit(1);  
 }  
 /*  
  * Send the request  
  */  
 if(write(s, user, strlen(user)) != strlen(user)){  
      fprintf(stderr, "%s: write error\n", myname);  
      exit(1);  
 }  
 /*  
  * Read the reply and put to user's output  
  */  
 while( (len =read(s, buf, BUFSIZ)) > 0)  
      write(1, buf, len);  
 close(s);  
 exit(0);  
 }  


Y aquí el servidor.

 /* whoisserver.c - main */  
 #include <stdio.h>  
 #include <stdlib.h>  
 #include <string.h>  
 #include <sys/types.h>  
 #include <sys/socket.h>  
 #include <netinet/in.h>  
 #include <netdb.h>  
 #include <pwd.h>  
 /*______________________________________________________________  
  * Program:      whoisserver  
  *   
  * Purpose:   UNIX application program that acts as a server for   
  *          the "whois" service on the local machine. It listens  
  *          on well-known WHOIS port (43) and anwers queries from  
  *          client. This program requires super-user privilege to   
  *          run.  
  * Use:      whois hostname username  
  *  
  *______________________________________________________________________  
  */  
 #define BACKLOG   5                     /* # of requests we're willing to queve */  
 #define MAXHOSTNAME 32                    /* maximum host name length we tolerate */  
 main(argc, argv)  
      int argc;                    /* standard UNIX argument declarations */  
      char *argv[];  
 {  
      int s, t;                    /*socket descriptors               */  
      int i;                         /*general purpose integer          */  
      struct sockaddr_in sa, isa;          /*Internet socket structure          */  
      struct hostent *hp;               /*result of host name lookup          */  
      char *myname;                    /*pointer to name of this program     */  
       struct servent *sp;               /*result of service lookpup          */  
      char localhost[MAXHOSTNAME+1];      /*local host name as character string  */  
      myname = argv[0];  
      /*  
       * Look up the WHOIS service entry  
       */  
      if ((sp = getservbyname("whois", "tcp")) == NULL) {  
           fprintf(stderr, "%s: No whois service on this host\n", myname);  
           exit(1);  
      }  
      /*  
       * Fet our own host information  
       */  
      gethostname(localhost, MAXHOSTNAME);  
      if((hp = gethostbyname(localhost)) == NULL){  
           fprintf(stderr, "%s: cannot get local host info?\n", myname);  
           exit(1);  
      }  
      fprintf(stderr,"localhost: %s \n", localhost); /*BARROS */  
      /*  
       * Put the WHOIS socket number and our addres info  
       * into the socket structure  
       */  
      sa.sin_port = sp->s_port;  
      bcopy((char *)hp->h_addr, (char *)&sa.sin_addr, hp->h_length);  
      sa.sin_family = hp->h_addrtype;  
      /*   
       * Allocate an open socket for incoming connections  
       */  
      if((s = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) {  
           perror("socket");  
           exit(1);       
      }  
      /*  
       * Bind the socket to the service port  
       * so we hear incoming connections  
       */  
      if(bind(s, (struct sockaddr*)&sa, sizeof sa) < 0) {  
           perror("bind");  
           exit(1);  
      }  
      /*  
       * Set maximum connections we will fall behind  
       */  
      listen(s, BACKLOG);  
      /*  
       * Go into an infinite loop waiting far new connections  
       */  
      while(1) {  
           i = sizeof isa;  
           fprintf(stderr,"i isa: %d , puerto %d , dirección %d\n", i, isa.sin_port, isa.sin_addr.s_addr); /*BARROS */  
           /*   
            * We hang in accept() while waiting for new customers  
            */  
           if((t = accept(s, (struct sockaddr*)&isa, &i)) < 0) {  
                perror("accept");  
                exit(1);  
           }  
           whois(t);               /* perform the actual WHOIS service */  
           close(t);  
      }  
 }  
      /*  
       * Get the WHOIS request from remote host and format a reply.  
       */  
      whois(sock)  
      int sock;  
 {  
      struct passwd *p;  
      char buf[BUFSIZ+1];  
      int i;  
      /*  
      * Get one line request  
       */  
      if((i =read(sock, buf, BUFSIZ)) <= 0)  
           return;  
      buf[i] = '\0';                    /* Null terminate */  
      /*  
        * Look up the requested user and format reply  
       */  
      if((p = getpwnam(buf)) == NULL)  
           strcpy(buf,"User not found\n");  
      else  
           sprintf(buf, "%s: %s\n", p->pw_name, p->pw_gecos);  
      /*  
        * Return reply  
       */  
      write(sock, buf, strlen(buf));  
      return;  
 }