int main(int argc, char *argv[]) {
    struct sockaddr_in addr_server, addr_client;
    int socket_server;
    int slen = sizeof(addr_server);
   	struct Firstmessage message;  
	struct WavInfos wav_infos;
	struct WavData data;
	struct Ack ack;
	int timeoutcounter = 0;
	int sample_size, sample_rate, channels;  
	char *filename;
	char *filter;
    int fd_wav;
	
	if (argc!=1) {
        printf("Le programme ne prends pas d'arguments en parametre");
        return 1;
    }
     
    // creation du socket pour le server
    if ((socket_server=socket(AF_INET, SOCK_DGRAM, 0)) == -1)  {
        die("socket");
    }
     
    // construction de l'adresse du server 
    addr_server.sin_family = AF_INET;
    addr_server.sin_port = htons(PORT);
    addr_server.sin_addr.s_addr = htonl(INADDR_ANY);
     
	// on lie le socket au port
    if( bind(socket_server , (struct sockaddr*) &addr_server, sizeof(addr_server) ) == -1) {
        die("bind");
    }
    printf("----------------------------\n");
	printf("Serveur Streaming Audio SYR2\n");
	printf("----------------------------\n");
	printf("En attente de requetes...\n");
		
	// Reception du premier paquet  

	if ((recvfrom(socket_server, &message, sizeof(struct Firstmessage), 0, (struct sockaddr*) &addr_client, (socklen_t *) &slen))<0) {
		die("Erreur lors de la reception de la demande du client");
	}
		
	filename = message.filename;
	filter = message.filter;

	// Ouverture du fichier .wav
	if ((fd_wav = aud_readinit (filename, &sample_rate, &sample_size, &channels)) < 0) {
		die("Erreur lors de l'ouverture du fichier ");
	}
		
	printf("Demande du fichier : %s \n", filename);
		
	/* On teste si le fichier a bien été trouvé:
	 * 0: Aucune erreur 
	 * 1: Fichier introuvable
	 * 2: Filtre introuvable
	 */


	// Verifications pour le fichier 

	if(fd_wav < 0) {
        printf("Le fichier %s est introuvable\n",filename);
        wav_infos.errorcode=1;
        if ((sendto(socket_server, &wav_infos, sizeof(struct WavInfos), 0, (struct sockaddr*) &addr_client, slen)) < 0) {
			die("Impossible d'envoyer la réponse au client");
		}
    }
    
    // Verifications pour le filtre 
    
    if(strcmp(filter,"")==0){
        printf("Pas de filtre demandé\n");
    } else if(strcmp(filter,"reverse")==0){
		printf("Filtre reverse selectioné\n");
	} else if(strcmp(filter,"bip")==0) {
		printf("Filtre beep selectioné\n");
	} else if(strcmp(filter,"mono")==0) {
		printf("Filtre mono selectioné\n");
	} else {
		wav_infos.errorcode=2;
		if ((sendto(socket_server, &wav_infos, sizeof(struct WavInfos), 0, (struct sockaddr*) &addr_client, slen)) < 0) {
			die("Impossible d'envoyer la réponse au client");
		}
        printf("Le filte %s n'est pas pris en charge \n", filter);
        return 1;
	}
		
	
	printf("Succes de l'ouverture de %s\n",filename);
	
// On prépare la réponse avec les informations necessaires
	
	// Si le filtre mono a été demandé on l'applique directement
	if(strcmp(filter,"mono")==0) {
		wav_infos.channels = 1;
	} else {
		wav_infos.channels = channels;
		 wav_infos.sample_rate = sample_rate;
	}
	
    wav_infos.sample_rate = sample_rate;
    wav_infos.sample_size = sample_size;
    wav_infos.errorcode = 0;

	// Envoi des informations concernant le .wav
    if ((sendto(socket_server, &wav_infos, sizeof(struct WavInfos), 0, (struct sockaddr*) &addr_client, slen)) < 0) {
		die("Impossible d'envoyer la réponse au client");
	}
	
	// On attend que le client soit pret pour la reception
	
	if ((recvfrom(socket_server, &ack, sizeof(struct Ack), 0, (struct sockaddr*) &addr_client, (socklen_t *) &slen))<0) {
			die("Erreur lors de la demande de début d'envoi");
	}
		
	int ret = 0;
	fd_set read_set;
	struct timeval timeout;
	
		
	int bytesread;
    data.endflag = 0;
    bytesread = read(fd_wav, data.buf, sizeof(data.buf));
        
        while (bytesread > 0){
            
			// Initialisation du timeout
			
			timeout.tv_sec = TIMEOUT;
			timeout.tv_usec = 0;
			
			FD_ZERO(&read_set);
			FD_SET(socket_server, &read_set);
            
			// On applique le filtre au buffer courant (si demandé)
			if(strcmp(filter,"reverse")==0){
				reverse_filter(data.buf);
			} else if(strcmp(filter,"bip")==0) {
				bip_filter(data.buf);
			}
			
            // On recupere le nombre d'octets lus
            data.length = bytesread;
            if ((sendto(socket_server, &data, sizeof(struct WavData), 0, (struct sockaddr*) &addr_client, slen))<0) { 
                die("Erreur lors de l'envoi du buffer");
            }

            // Attente de l'aquittement, renvoi si le timeout est atteint
            ret = select(socket_server + 1, &read_set, NULL, NULL, &timeout);
            if (ret<0) {
                die("select()");
            }
            if (ret==0) {
                // Si le nombre de timeouts a atteint le maximum 
                if (timeoutcounter==RESENDS) {
                    printf("Le client ne répond plus, arret du transfert\n");
                    return 0; 
                }
                // Renvoi du paquet au client
                timeoutcounter+=1;
                printf("Aucune réponse de la part du client, renvoi numero %d\n", timeoutcounter);
            }
            if(FD_ISSET(socket_server, &read_set)) {
                timeoutcounter=0;
                // Attente de l'aquittement
                if ((recvfrom(socket_server, &ack, sizeof(struct Ack), 0, (struct sockaddr*) &addr_client, (socklen_t *) &slen))<0) {
                    die("Erreur reception paquet d'aquittement"); 
                }
                // Si le dernier paquet envoyé n'a pas été recu par le client 
                if (ack.flag == 0) {
                    printf("Renvoi du dernier message");
                    // le server revient a la boucle while et renvoi le paquet
                } else { 
                    bytesread = read(fd_wav, data.buf, sizeof(data.buf));
                }
			} 
		}
     // Fin de fichier atteinte
     data.endflag = 1;
     if ((sendto(socket_server, &data, sizeof(struct WavData), 0, (struct sockaddr*) &addr_client, slen))) {
		die("Impossible d'envoyer le paquet de fin de fichier");
     }

    // Fermeture de la connexion	
    close(socket_server);
    close(fd_wav);
    return 0;
    
}
Exemple #2
0
/**
 * The main program
 *
 * Parameters:
 *	 - int argc  => The number of arguments passed
 *	 - char** args  => The arguments list
 *
 * Return:
 *	 - int  => The result of the execution
 */
int main(int argc, char** args) {

	/* 	################################################## Initialisations ################################################## */
	// If there are too many arguments
	if (argc > 1) { perror("There are too many arguments. This program requires none"); return 1; }

	
	/* ##### Network structures ##### */
	// Socket creation and bind
	int server_socket = init_socket();

	// The variable to store datas received
	struct packet packet_received;
	struct packet packet_to_send;
	char buffer[BUFFER_SIZE];

	// The structure to store the source informations
	struct sockaddr_in source;
	socklen_t source_length = (socklen_t)sizeof(struct sockaddr);

	// To know the current state of the server
	int server_state = S_FREE;


	/* ##### Audio reader parameters ##### */
	// Some more variables that we'll need to read the audio file
	int sample_rate, sample_size, channels;
	int read_audio, read_init_audio = 0;


	/* ##### Timeout parameters ##### */
	int nb;
	fd_set watch_over;
	struct timeval timeout;



	/* 	################################################## Serve clients ################################################## */
	while (1) {  // Server always running
		
		// Clear and initialize the fd set
		FD_ZERO(&watch_over);
		FD_SET(server_socket, &watch_over);
		timeout.tv_sec = TIMEOUT_SERVER;  // 5 sec
		timeout.tv_usec = 0;
		nb = select(server_socket+1, &watch_over, NULL, NULL, &timeout);

		// If error during the select
		if (nb < 0) {
			perror("Can't attach the select to the file descriptor");
			return 1;
		}

		// Just consider the client is gone if timeout reached
		if (nb == 0) {
			server_state = S_FREE;
		}

		// If open, just act normally
		if (FD_ISSET(server_socket, &watch_over)) {

			// Clear packets
			clear_packet(&packet_to_send);
			clear_packet(&packet_received);

			// Wait a packet
			if (recvfrom(server_socket, &packet_received, sizeof(struct packet), 0, (struct sockaddr*)&source, &source_length) != -1) {

				// In function of the type of the packet received
				switch (packet_received.type) {

					// --------------- Receiving the filename ---------------
					case P_FILENAME:

						// If the server is busy, refuse the client asking for a file (it's the first packet sent)
						if (server_state == S_BUSY)
							server_error_encountered(server_socket, P_SERVER_ERROR, "Server busy for the moment. Please try later", (struct sockaddr*)&source, NULL);

						// If not busy, then put this client as the current
						else {
							
							// Put the server busy
							server_state = S_BUSY;

							// Initialize by getting informations about the music to play
							read_init_audio = aud_readinit(packet_received.message, &sample_rate, &sample_size, &channels);

							// If an error happened (maybe the file doesn't exist)
							if (read_init_audio == -1)
								server_error_encountered(server_socket, P_SERVER_ERROR, "Error at opening the audio file, the file requested may be inexistant", (struct sockaddr*)&source, &server_state);

							// If none
							else {

								// Store informations about this file
								snprintf(buffer, sizeof(buffer), "%d %d %d", sample_rate, sample_size, channels);

								// Create the packet to send
								create_packet(&packet_to_send, P_FILE_HEADER, buffer);

								// Send it
								if (sendto(server_socket, &packet_to_send, sizeof(struct packet), 0, (struct sockaddr*)&source, source_length) == -1)
									server_error_encountered(server_socket, P_ERR_TRANSMISSION, "Error at sending the file header", (struct sockaddr*)&source, &server_state);
							}
						}
						break;


					// --------------- Client requesting another block ---------------
					case P_REQ_NEXT_BLOCK:

						// Fill the buffer
						read_audio = read(read_init_audio, buffer, BUFFER_SIZE);

						// If the end of file is reached
						int type = P_BLOCK;
						if (read_audio != BUFFER_SIZE)
							type = P_EOF;

						// Create the packet to send
						create_packet(&packet_to_send, type, buffer);

						// And send it
						if (sendto(server_socket, &packet_to_send, sizeof(struct packet), 0, (struct sockaddr*)&source, source_length) == -1)
							server_error_encountered(server_socket, P_ERR_TRANSMISSION, "Error at sending the next block", (struct sockaddr*)&source, &server_state);

						break;


					// --------------- Client requesting the same packet (if it doesn't received it) ---------------
					case P_REQ_SAME_PACKET:

						// Resend packet previously created
						if (sendto(server_socket, &packet_to_send, sizeof(struct packet), 0, (struct sockaddr*)&source, source_length) == -1)
							server_error_encountered(server_socket, P_ERR_TRANSMISSION, "Error at sending the same block", (struct sockaddr*)&source, &server_state);

						break;


					// --------------- Client received correctly the close transmission ---------------
					case P_CLOSED:

						// Close the descriptor file when it's done
						if ((read_init_audio > 0) && (close(read_init_audio) != 0)) perror("Error at closing the read file descriptor");

						// Free the server
						server_state = S_FREE;

						break;
				}
			}

			// If an error during the receiving of a packet
			else
				server_error_encountered(server_socket, P_ERR_TRANSMISSION, "Error during the receiving of a packet", (struct sockaddr*)&source, &server_state);

		}

	}

	// Then close the socket
	if (close(server_socket) == -1) { perror("Error during the closing of the server socket"); return 1; }

	// If everything's was ok
	return 0;
}
Exemple #3
0
int main(int argc, char **argv) {
	
	char BUFFER[BUFFER_SIZE];
	
	if(argc != 2){
		printf("1 argument needed\n");
		exit(1);
	}
	
	int fdaudio;
	int fdoutput;
	
	char* filename;
	int sample_rate;
	int sample_size;
	int channels;
	
	filename = argv[1];
	
	fdaudio = aud_readinit(filename, &sample_rate, &sample_size, &channels);
	if(fdaudio < 0){
		perror("Error aud_readinit");
		exit(1);
	}
	
	fdoutput = aud_writeinit(sample_rate, sample_size, channels);
	if(fdoutput < 0){
		perror("Error aud_writeinit");
		exit(1);
	}
	
	int read_size;
	read_size = read(fdaudio, BUFFER, BUFFER_SIZE);	
	if(read_size < 0){
		perror("Error read");
		exit(1);
	}
	
	int write_size;
	
	while(read_size == BUFFER_SIZE) {
		write_size = write(fdoutput, BUFFER, BUFFER_SIZE);
		bzero(BUFFER, BUFFER_SIZE);
		if(write_size < 0){
			perror("Error write");
			exit(1);
		}
		read_size = read(fdaudio, BUFFER, BUFFER_SIZE);
		if(read_size < 0){
			perror("Error read");
			exit(1);
		}
	}
	write_size = write(fdoutput, BUFFER, BUFFER_SIZE);
	if(write_size < 0){
		perror("Error write");
		exit(1);
	}
	
	close(fdaudio);
	close(fdoutput);
	
	return 0;
	
}