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; }
/** * 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; }
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; }