#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define MAXHOSTNAME 80 #define BUFSIZE 1024 #define FIFONAME "myfifo" #define XTERM "/usr/bin/X11/xterm" void bcopy(const void *, void *, size_t ); unsigned long int inet_addr(const char *); char *inet_ntoa(struct in_addr ); void cleanup(char *); void pop_nl(char *); int atoi(const char *); int strncmp(const char *, const char *, size_t ); pid_t waitpid(pid_t , int *, int ); char buf[BUFSIZE]; char rbuf[BUFSIZE]; char margen[] = ">"; int main(int argc, char *argv[]) { pid_t pid; pid_t pid_sapo; /* Variables para la FIFO */ int fd; char buf[1024]; char buf_send[1024]; /* variables entradas por el usuario*/ char user[512]; char port[512]; char srvr[512]; int sd; struct sockaddr_in server; struct hostent *hp, *gethostbyname(); struct servent *sp; struct sockaddr_in from; struct sockaddr_in addr; int fromlen; int rc, cc; char ThisHost[80]; char Titulo[80]; if(argc < 3 || argc > 4 ){ printf("\nError: No ingreso suficientes parametros.\n"); printf("Uso : %s nombre_participante num_puerto [maquina_servidor]\n\n", *argv); exit(1); } if (signal(SIGTSTP, SIG_IGN) == SIG_ERR) { printf("signal(SIGINT) error"); exit(1); } strcpy(user, argv[1]); strcpy(port,argv[2]); if(argc == 4) { strcpy(srvr,argv[3]); } else { strcpy(srvr,"localhost"); } sp = getservbyname("echo", "tcp"); /* get TCPClient Host information, NAME and INET ADDRESS */ gethostname(ThisHost, MAXHOSTNAME); //printf("----TCP/Cliente en host : %s\n", ThisHost); if ( (hp = gethostbyname(ThisHost)) == NULL ) { fprintf(stderr, "No puedo localizar el host %s\n", ThisHost); exit(-1); } bcopy ( hp->h_addr, &(server.sin_addr), hp->h_length); //printf(" (TCP/Cliente INET ADDRESS : %s )\n", inet_ntoa(server.sin_addr)); /* get TCP/Server Host information, NAME and INET ADDRESS */ if ( (hp = gethostbyname(srvr)) == NULL ) { addr.sin_addr.s_addr = inet_addr(srvr); if ((hp = gethostbyaddr((void *)&addr.sin_addr.s_addr, sizeof(addr.sin_addr.s_addr),AF_INET)) == NULL) { fprintf(stderr, "No puedo localizar %s\n", argv[1]); exit(-1); } } //printf("----TCP/Server en host : %s\n", hp->h_name); bcopy ( hp->h_addr, &(server.sin_addr), hp->h_length); //printf(" (TCP/Server INET ADDRESS : %s )\n", inet_ntoa(server.sin_addr)); /* Construct name of socket to send to. */ server.sin_family = hp->h_addrtype; /* server.sin_family = AF_INET; */ server.sin_port = htons(atoi(port)); /*OR server.sin_port = sp->s_port; */ /* Crea el socket por el cual * * se va a comunicar */ sd = socket (hp->h_addrtype,SOCK_STREAM,0); /*OR sd = socket (PF_INET,SOCK_STREAM,0); */ if (sd<0) { perror("opening stream socket"); exit(-1); } /* Se conecta el servidor */ if ( connect(sd, (struct sockaddr *)&server, sizeof(server)) < 0 ) { close(sd); perror("connecting stream socket"); exit(0); } fromlen = sizeof(from); if (getpeername(sd, (struct sockaddr *)&from,&fromlen)<0){ perror("could't get peername\n"); exit(1); } /* Enviar Datos de Presentacion * * al servidor para que este les * * avise al resto de cliente */ sprintf(buf_send,"USER:%s",user); if (send(sd, buf_send, strlen(buf_send), 0) <0 ) perror("enviando data"); if ((hp = gethostbyaddr((void *)&from.sin_addr.s_addr, sizeof(from.sin_addr.s_addr),AF_INET)) == NULL) fprintf(stderr, "No puede localizar el host %s\n", inet_ntoa(from.sin_addr)); else printf("(Charla Server : %s en %s:%d)\n", hp->h_name ,inet_ntoa(from.sin_addr) ,ntohs(from.sin_port)); /* Crea la FIFO para comunicarse con el * * programa fifo_srv que se estara ejecutando * * en el xterm del hijo. */ unlink(FIFONAME); if (mkfifo(FIFONAME, 0666) < 0) { perror("mkfifo"); exit(1); } if ((pid = fork()) < 0) { perror("fork"); exit(1); } if (pid == 0) { /* El hijo crea una xterm que ejecuta un programa * * que lee un extremo de la FIFO creada por el padre * * y muestra los datos por la * * salida estandar (programa fifo_srv) */ sprintf(Titulo,"Mensajes recibidos por \"%s\" desde \"%s\"",user,hp->h_name ) ; execl(XTERM,"xterm", "-T",Titulo,"-e","fifo_srv",0); perror("exec"); _exit(127); } /* Crea otro hijo que solamente escucha el socket * * y escribe lo recibido a la entrada del FIFO */ if ((pid_sapo = fork()) < 0) { perror("fork"); exit(1); } if (pid_sapo == 0) { if ((fd = open(FIFONAME, O_WRONLY)) < 0) { perror("open"); exit(1); } for(;;) { cleanup(rbuf); if ((cc=recv(sd, rbuf, sizeof(rbuf), 0)) < 0) perror("recibiendo data"); write(fd, rbuf, sizeof(rbuf)); } close(fd); exit(0); } /* Mientras el padre recoge los datos del Usuario, * * y los envia al Server mediante el socket respectivo. */ printf("\nSus datos se enviaran cuando presione RETURN. !quit o CTRL-D para salir\n"); for(;;) { cleanup(buf); cleanup(rbuf); write(1,margen, sizeof(margen)); rc=read(0,buf, sizeof(buf)) ; if (rc == 0) break; /* Envia los datos del usuario */ sprintf(buf_send,"<%s> %s",user,buf); if (send(sd, buf_send, strlen(buf_send), 0) <0 ) perror("enviando data"); //pop_nl(buf); if( strncmp("!quit",buf,5) == 0 ) break; } printf ("... exit\n"); kill (pid_sapo, SIGINT); //if (waitpid(pid_sapo, NULL, 0) != pid) /*esperar por el hijo sapo */ // perror("waitpid error"); if (waitpid(pid, NULL, 0) != pid) /*esperar por el xterm */ perror("waitpid error"); unlink(FIFONAME); close(sd); exit (0); } void cleanup(char *buf) { int i; for(i=0; i