#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /* estructura que contiene datos a enviar */ typedef struct packet { int length; char name[50]; char msg[256]; } Packet; /* Programa Principal */ int main( int argc, char * argv[] ) { pid_t Pid; /* Grupo, variable con información de conexión */ struct sockaddr_in Grupo; int Soquet, status1, status2, Reusar, i, salir; /* Paquete contiene la información a enviar */ Packet Paquete; /* Minfo contiene informacion para multicast */ struct ip_mreq Minfo; unsigned int mcGroup; char loop, ttl, *comando; /* Variables para Select */ fd_set readfds, readfdsCopy; if (argc != 4) { printf("\nSintaxis 'mcharla' : mcharla \n\n"); exit(0); } comando=(char*)malloc(50); salir=0; /* Presentación del programa */ printf("***************************************************\n"); printf("* *\n"); printf("* mcharla *\n"); printf("* *\n"); printf("***************************************************\n"); printf("* *\n"); printf("* CREDITOS: *\n"); printf("* Javier Villalobos Arancibia *\n"); printf("* jvillalo@alumnos.utfsm.cl *\n"); printf("* *\n"); printf("* Para obtener ayuda, tipee '/ayuda' *\n"); printf("* *\n"); printf("***************************************************\n\n"); printf("Listo para recibir mensajes:\n\n"); strcpy(Paquete.name, argv[1]); /* Creación de Socket */ Soquet=socket (PF_INET,SOCK_DGRAM,0); Reusar=1; if (setsockopt(Soquet ,SOL_SOCKET,SO_REUSEADDR,(char *) &Reusar,sizeof(Reusar)) == -1 ) { printf("error en 'setsockopt',SO_REUSEPORT \n"); exit(-1); } Grupo.sin_family = AF_INET; Grupo.sin_addr.s_addr = htonl(INADDR_ANY); Grupo.sin_port = htons(atoi(argv[3])); if (bind(Soquet,(struct sockaddr *)&Grupo, sizeof(Grupo)) < 0) { printf("Imposible realizar Bind\n"); exit (-1); } if ((mcGroup = inet_addr(argv[2]))== -1) printf("Error en inet_addr\n"); Minfo.imr_multiaddr.s_addr = mcGroup; Minfo.imr_interface.s_addr = INADDR_ANY; if (setsockopt(Soquet,IPPROTO_IP,IP_ADD_MEMBERSHIP,(char *) &Minfo, sizeof(Minfo)) == -1 ) { printf("Error al ingresar al grupo\n"); exit(-1); } Grupo.sin_addr.s_addr= mcGroup; loop = 1; if (setsockopt(Soquet, IPPROTO_IP,IP_MULTICAST_LOOP,(char *) &loop, sizeof(u_char)) == -1 ) { printf("Error al setear el loopback\n"); } ttl = 5; if (setsockopt(Soquet,IPPROTO_IP,IP_MULTICAST_TTL,(char *) &ttl, sizeof(u_char)) == -1 ) { printf("Error al setear el valor del loopback\n"); } FD_ZERO(&readfdsCopy); FD_SET(Soquet,&readfdsCopy); FD_SET(0,&readfdsCopy); /* Creación de proceso hijo que ejecuta programa Mensajes, en nueva ventana */ if ((Pid=fork())==0) { execlp("xterm","xterm","-e","./Mensajes",argv[1],argv[2],argv[3],(char *)0); return(0); } for(;;) { memcpy(&readfds, &readfdsCopy, sizeof(fd_set)); status1 = select(FD_SETSIZE, &readfds, (fd_set *) 0, (fd_set *) 0, NULL); if (status1 > 0) { strcpy(comando," \0"); if (FD_ISSET(0, &readfds)) { /* Lee desde teclado */ status2=read(0,Paquete.msg, 256); if (status2 == 0) break; /* Revisa si se ha escrito un comando */ if (Paquete.msg[0]=='/') { for (i=1;i<5;i++) comando[i-1]=Paquete.msg[i]; comando[4]='\0'; /* Si comando es /quit, prepara salida del programa */ if (strcmp(comando,"quit")==0) salir=1; } Paquete.msg[status2-1]='\0'; /* Presenta la Ayuda, en caso de comando = /ayuda */ if (strcmp(Paquete.msg,"/ayuda")==0) { printf("\nAYUDA:\n"); printf("\nmcharla permite algunos comandos para mensajes:\n"); printf("\n/me : Permite enviar un mensaje en tercera persona.\n"); printf("\n/saludo : Permite enviar un mensaje de saludo a .\n"); printf("\n/maldicion : Permite enviar una maldicion a .\n"); printf("\n/quit : Sale de mcharla\n"); printf("\nFIN AYUDA\n\n"); } else { /* Envia mensaje al Soquet */ Paquete.length = sizeof(Paquete)-256+status2; if (sendto(Soquet, (char *)&Paquete, Paquete.length, 0, (struct sockaddr*)&Grupo,sizeof(Grupo)) <0 ) printf("\nError al enviar datos\n"); if (salir) break; } } } } /* Saliendo del programa */ Minfo.imr_multiaddr.s_addr = mcGroup; Minfo.imr_interface.s_addr = INADDR_ANY; if(setsockopt(Soquet,IPPROTO_IP,IP_DROP_MEMBERSHIP, (char *) &Minfo,sizeof(Minfo)) == -1 ) { printf("Error al intentar desconectarse\n"); exit(-1); } /* cierra ventana de mensajes y abandona el programa */ kill(Pid,SIGKILL); return(0); }