You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
131 lines
3.2 KiB
131 lines
3.2 KiB
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <errno.h>
|
|
#include <unistd.h> /* pour read(2)/write(2) */
|
|
|
|
#include <netdb.h>
|
|
#include <string.h> /* pour memset */
|
|
|
|
#include <ctype.h> /* pour toupper */
|
|
|
|
#include <arpa/inet.h> /* pour inet_ntop */
|
|
|
|
#define REQUEST_MAX 1024 /* taille MAX en réception */
|
|
#define BUFFER_SIZE 1024
|
|
|
|
void usage() {
|
|
fprintf(stderr,"usage : serveur port fichier\n");
|
|
exit(1);
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
int s, sock, ret;
|
|
|
|
struct addrinfo hints, *result;
|
|
|
|
struct sockaddr_storage src_addr;
|
|
socklen_t len_src_addr;
|
|
|
|
char request[REQUEST_MAX];
|
|
|
|
/* Vérification des arguments */
|
|
if(argc!=3) {
|
|
fprintf(stderr,"Erreur : Nb args !\n");
|
|
usage();
|
|
}
|
|
memset(&hints, 0, sizeof(struct addrinfo));
|
|
hints.ai_flags = AI_PASSIVE; /* Equiv INADDR_ANY */
|
|
hints.ai_family = AF_INET6; /* Allow IPv4 or IPv6 */
|
|
hints.ai_socktype = SOCK_STREAM; /* Flux => TCP */
|
|
hints.ai_protocol = 0; /* Any protocol */
|
|
hints.ai_canonname = NULL;
|
|
hints.ai_addr = NULL;
|
|
hints.ai_next = NULL;
|
|
|
|
ret = getaddrinfo(NULL, argv[1], &hints, &result);
|
|
if (ret != 0) {
|
|
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(ret));
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Création de la socket IPv4/IPv6 */
|
|
if((s=socket(result->ai_family, result->ai_socktype,
|
|
result->ai_protocol))==-1) {
|
|
perror("socket"); exit(1);
|
|
}
|
|
|
|
/* Attachement de la socket */
|
|
|
|
if (bind(s, result->ai_addr, result->ai_addrlen) == -1) {
|
|
perror("bind"); exit(1);
|
|
}
|
|
|
|
freeaddrinfo(result);
|
|
|
|
/* définition de la taille de la file d'attente */
|
|
|
|
if(listen(s, 5)) {
|
|
perror("listen"); exit(1);
|
|
}
|
|
|
|
FILE *file = fopen(argv[2], "rb");
|
|
if (!file) {
|
|
perror("Pb fichier, impossible ouverture !");
|
|
close(sock);
|
|
exit(errno);// Move on to the next client
|
|
}
|
|
|
|
while(1) { /* boucle du serveur */
|
|
|
|
/* Attente d'une connexion */
|
|
|
|
puts("En attente de connexion...");
|
|
|
|
len_src_addr=sizeof src_addr;
|
|
if((sock=accept(s, (struct sockaddr *)&src_addr,
|
|
&len_src_addr))==-1) {
|
|
perror("accept"); exit(1); // exit errno que si on s'en sert.
|
|
}
|
|
|
|
puts("Connexion acceptée !");
|
|
|
|
rewind(file);
|
|
|
|
/* boucle de traitement du client */
|
|
|
|
// while((ret=recv(sock, request, REQUEST_MAX,0))>0) {
|
|
|
|
// request[ret]=0;
|
|
|
|
// /* traitement de la requête(passage en majuscule) */
|
|
// {
|
|
// int i=0;
|
|
// Send file content to client
|
|
unsigned char buffer[BUFFER_SIZE];
|
|
size_t bytesRead;
|
|
while ((bytesRead = fread(buffer, 1, BUFFER_SIZE, file)) != 0) {
|
|
if (send(sock, buffer, bytesRead, 0) == -1) {
|
|
perror("Pb impossible d'envoyer le fichier au client");
|
|
fclose(file);
|
|
close(sock);
|
|
continue;
|
|
}
|
|
}
|
|
// }
|
|
// } /* fin de la boucle de traitement du client */
|
|
|
|
if(close(sock)==-1 && fclose(file)==-1) {
|
|
perror("close"); exit(errno);
|
|
}
|
|
|
|
fprintf(stderr, "Fin de connexion !\n");
|
|
if(ret==-1) {
|
|
perror("recv");
|
|
}
|
|
|
|
} /* fin boucle principale du serveur */
|
|
|
|
return 0;
|
|
} |