La aplicación receive captura todos los paquetes enviados al puerto de escucha, extrae el audio que contienen y lo escribe sobre su salida estándar.
/******************************************************************************
* receive.c -- Receptor de datos a través de UDP. * * Recibe un flujo de datos a través de un puerto y lo copia a la * salida estándard. * * gse. 2005. *****************************************************************************/ /****************************************************************************** * * Ficheros cabecera. * *****************************************************************************/ /* Entrada y salida de streams buffereados. */ #include <stdio.h> /* Biblioteca de funciones estándar (exit(), EXIT_SUCCESS, EXIT_FAILURE, ...) */ #include <stdlib.h> /* Manipulación de cadenas y movimiento de memoria (memset(), ...). */ #include <string.h> /* Biblioteca estándar de funciones relacionadas con el sistema operativo Unix (read(), write(), getopt(), ...). */ #include <unistd.h> #include <fcntl.h> /* Sockets. */ /* Más info en: * * http://www.csce.uark.edu/~aapon/courses/os/examples/concurrentserver.c * http://www.fortunecity.com/skyscraper/arpanet/6/cc.htm * http://beej.us/guide/bgnet/ */ /* Tipos de datos primitivos del sistema. */ #include <sys/types.h> /* Sockets (socket(), listen(), ...). */ #include <sys/socket.h> /* Direcciones IP, opciones y definiciones. */ #include <netinet/in.h> /* Servicio de resolución de nombres. */ #include <netdb.h> /* Signals (interrupciones) (signal(), SIGINT). */ #include <signal.h> /* signal() */ /****************************************************************************** * * Definiciones. * *****************************************************************************/ /* Número de bytes del buffer de audio. */ #define BUFFER_SIZE 512 /* Puerto destino de los datagramas. */ #define LISTENING_PORT 6666 /****************************************************************************** * * Variable globales. * *****************************************************************************/ int sd; /* Socket descriptor */ /****************************************************************************** * * Funciones. * *****************************************************************************/ /* Cuerpo principal del programa. */ int main(int argc, char *argv[]) { work(argc, argv); return EXIT_SUCCESS; } work(int argc, char *argv[]) { /* Si pulsamos CRTL+C, el programa acaba ejecutando la función end(). */ void end() { fprintf(stderr,"receive: CTRL+C detected. Exiting ... "); close(sd); fprintf(stderr,"done\n"); exit(EXIT_SUCCESS); } signal(SIGINT, end); //activando la senal SIGINT /* Tamaño del buffer. */ int buffer_size = BUFFER_SIZE; /* Dirección origen por defecto de los datagramas. */ char *source_hostname = "localhost"; /* Puerto destino por defecto de los datagramas. */ int listening_port = LISTENING_PORT; int c; while ((c = getopt (argc, argv, "b:h:p:")) != -1) { switch (c) { case ’b’: buffer_size = atoi(optarg); break; case ’h’: source_hostname = optarg; break; case ’p’: listening_port = atoi(optarg); break; case ’?’: if (isprint (optopt)) fprintf (stderr, "Unknown option ‘-%c’.\n", optopt); else fprintf (stderr, "Unknown option character ‘\\x%x’.\n", optopt); return 1; default: abort (); } } fprintf(stderr,"%s: buffer size = \"%d\"\n", argv[0],buffer_size); fprintf(stderr,"%s: source hostname = \"%s\"\n", argv[0],source_hostname); fprintf(stderr,"%s: listening port = \"%d\"\n", argv[0],listening_port); /* Creamos el socket UDP bloqueante */ if((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket"); exit(EXIT_FAILURE); } /* Dir IP destino y puerto de escucha. */ struct sockaddr_in socket_addr; { /* Usaremos Internet */ socket_addr.sin_family = AF_INET; /* IP destino de los datagramas: cualquiera de mis interfaces. */ socket_addr.sin_addr.s_addr = htons(INADDR_ANY); /* Puerto de escucha. */ socket_addr.sin_port = htons(listening_port); memset(&(socket_addr.sin_zero), ’\0’, 8); } /* Cuando hagamos el bind(), si el puerto todavía no ha sido liberado por el SO, no tendremos que esperar a reutilizarlo. */ int yes=1; if(setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int))<0) { perror("setsockopt"); exit(EXIT_FAILURE); } /* Mapeamos el socket a un puerto de salida y a un interface de red */ if(bind(sd, (struct sockaddr *)&socket_addr, sizeof(struct sockaddr)) < 0) { perror("bind"); exit(EXIT_FAILURE); } char *buffer = (char *)malloc(buffer_size*sizeof(char)); for(;;) { /* Buffer con el audio */ //char buffer[BUFFER_SIZE]; /* Recibimos el datagrama */ struct sockaddr_in source_addr; socklen_t addr_len = sizeof(struct sockaddr_in); int bytes_read = recvfrom(sd, (void *)buffer, buffer_size, 0, (struct sockaddr *)&source_addr, &addr_len); /* Escribimos el datagrama a stdout */ write(1, (void *)buffer, bytes_read); } } |