// Procedure principale int main (int argc , char ** argv) { // Descripteur du serveur int serveur; // Adresse du client // Utilise par recvfrom pour recevoir les // informations du client qui a envoye une // demande de connexion struct sockaddr_in client; // Longueur de la structure utilise par client int long_client; // Pour le parcour du tabbleau des identificateurs des thread int i; // utilise pour guarder la Valeur de retour de recvfrom int recue; // Utiliser pour guarder la valeur de retour de sendto int envoye; // Utilise pour la lecture de la demande de connexion char *buf; int long_buf; // Pour lire la date time_t temp; // Contient le chemin du fichier historique char nom_hist[MAX_REP_CHEMIN + 1]; system("clear"); printf("\n Arguments de la ligne de commande ... "); if (argc != 2) { printf(" [FAILED]"); printf("\n Usage: serveur num_proto\n"); exit(1); } printf(" [OK]"); strcpy(nom_hist, "/historique"); printf("\n Creation du fichier %s ... ",nom_hist); hist = fopen(nom_hist,"w+"); if(hist == NULL) { printf(" [FAILED]\n"); perror("Cause"); exit(1); } printf(" [OK]\n"); time(&temp); fprintf(hist," -------------------------------------------------\n"); fprintf(hist,"| Ce fichier contient l'historique des connexions |\n"); fprintf(hist," -------------------------------------------------\n"); fprintf(hist," Date de creation: %s \n ", ctime(&temp) ); // Initialisation du buffer // On va essayer d'alloue MAX_BUF octet printf("\n Allocation du buffer ... "); fprintf(hist, "\n Allocation du buffer ... "); buf = (char *)malloc(MAX_BUF); if(buf == NULL) { printf("\n Impossible d'alloue de l'espace pour le buffer"); // Sans le buffer on ne peut rien faire exit(1); } printf(" [OK]"); fprintf(hist, " [OK]"); // Initialisation du tableau des threads printf("\n Initialisation du tableau d'id de thread ... "); fprintf(hist, "\n Initialisation du tableau d'id de thread ... "); for (i = 0; i < 4; i++) { th_occupe[i] = -1; } printf(" [OK]"); fprintf(hist, " [OK]"); // Initialisation num_libre a 0 num_libre = 0; // creation du socket fprintf(hist, "\n Creation de socket sur le port %d... ",atoi(argv[1])); printf("\n Creation de socket sur le port %d... ",atoi(argv[1])); serveur = cree_socket(atoi(argv[1]),hist); if(serveur == -1) { printf("\n Un probleme a interrompu la creation du socket.\n"); exit(1); } printf("\n \t Le serveur va entre dans une boucle infini \n"); printf(" \t ========================================= "); //////////////////////////////////////////////////////////// // Boucle de gestion des connexions // /////////////////////////////////////////////////////////// while(vrai) { fflush(stdout);//vidage de la sortie standard printf("\n \t **************************************************"); printf("\n \t *** Attente des demandes de connexion ***"); printf("\n \t **************************************************"); printf("\n"); // Le serveur attend une demande de connexion fprintf(hist, "\n Attente de demande de connexion ... "); long_buf = strlen("connect"); recue = recvfrom(serveur, buf, long_buf , 0, (struct sockaddr*)&client, &long_client); if (recue < 0) { fprintf(hist, " [FAILED]\n"); perror("Cause"); // S'il y a une erreur de reception en arrete tout exit(1); } fprintf(hist, " [OK]"); // On doit recupere les informations du client // qui a demande une connexion printf("\n %s:%u demande la connexion au serveur ...", inet_ntoa(client.sin_addr),ntohs(client.sin_port)); time(&temp); fprintf(hist, "\n Une demande de connexion est recue:\n"); fprintf(hist, " _==================================_\n"); fprintf(hist, "\t * Date de connexion: %s", ctime(&temp)); fprintf(hist, "\t * Famille du Socket client: %x\n", ntohs(client.sin_family)); fprintf(hist, "\t * Port client: %u\n", ntohs(client.sin_port)); fprintf(hist, "\t * IP client: %s\n", inet_ntoa(client.sin_addr)); if(strcmp(buf,"connect") == 0) { fprintf(hist, "\n Le client a envoye %s.", buf); fprintf(hist, " ... Requete valide"); } else { fprintf(hist, "\n Requete inconnu: Attendu connect recue %s", buf); continue ; } // Validation de la demande par un OK // Ceci n'est pas necessaire en mode connecte // car c'est la commande accepte qui realise cette tache fprintf(hist, "\n Le serveur envoi une reponse au %s:%u ...", inet_ntoa(client.sin_addr),ntohs(client.sin_port)); long_client = sizeof(client); if(num_libre > 3) { strcpy(buf,"NO"); long_buf = strlen("NO") + 1; envoye = sendto(serveur,buf,long_buf,0, (struct sockaddr *)&client, long_client); if(envoye < 0) { fprintf(hist, " [FAILED]\n"); perror("Cause"); continue ; } printf("\n Connexion du %s:%u refuse: depacement de capacite \n", inet_ntoa(client.sin_addr),ntohs(client.sin_port)); fprintf(hist, " [OK]\n"); fprintf(hist,"\n|**************************************************|"); fprintf(hist,"\n DEPACEMENT DE CAPACITE DU SERVEUR "); fprintf(hist, "\n Connexion du client %s:%u refuse ", inet_ntoa(client.sin_addr), ntohs(client.sin_port)); fprintf(hist,"\n|**************************************************|"); } else { strcpy(buf,"OK"); long_buf = strlen("OK") + 1; envoye = sendto(serveur,buf,long_buf,0, (struct sockaddr *)&client, long_client); if(envoye < 0) { fprintf(hist," [FAILED]\n"); perror("Cause"); continue; } fprintf(hist, " [OK]\n"); num_libre ++; // On cherche un identificateur libre for(i = 0; i < 4; i++) if(th_occupe[i] == -1) { // La structure special contient le nom de fichier // la chaine a recherche // et l'adresse du client // creation du thread associe au client fprintf(hist, "\n Creation de thread ... "); if( pthread_create(&th_id[i], NULL,(void *) th_trait, (void *)&client) != 0 ) { fprintf(hist, " [FAILED]\n"); exit(1); } th_occupe[i] = th_id[i]; break; } } freopen(nom_hist,"a+",hist); }// while(true) }
// Procedure principale int main (int argc , char ** argv) { // Descripteur du serveur int serveur; // Nouveau descripteur retourne par accept int nouv_sock; // Adresse du client // Utilise par recvfrom pour recevoir les // informations du client qui a envoye une // demande de connexion struct sockaddr_in client; // Longueur de la structure utilise par client int long_client; // Pour le parcour du tabbleau des identificateurs des thread int i; // utilise pour garder la Valeur de retour de recvfrom int recue; // Utiliser pour garder la valeur de retour de sendto int envoye; // Utilise pour la lecture de la demande de connexion char *buf; int long_buf; // Pour lire la date time_t temp; comp special; system("clear"); printf("\n Arguments de la ligne de commande ... "); if (argc != 2) { printf(" [FAILED]"); printf("\n Usage: serveur num_proto\n"); exit(1); } printf(" [OK]"); // Creation du fichier historique printf("\n Creation du fichier historique ... "); hist = fopen("historique","w+"); if(hist == NULL) { printf(" [FAILED]"); perror("Cause"); exit(1); } printf(" [OK]"); time(&temp); fprintf(hist," -------------------------------------------------\n"); fprintf(hist,"| Ce fichier contient l'historique des connexions |\n"); fprintf(hist," -------------------------------------------------\n"); fprintf(hist," Date de creation: %s \n ", ctime(&temp) ); // Initialisation du buffer // On va essayer d'alloue MAX_BUF octet printf("\n Allocation du buffer ... "); fprintf(hist, "\n Allocation du buffer ... "); buf = (char *)malloc(MAX_BUF); if(buf == NULL) { printf("\n Impossible d'alloue de l'espace pour le buffer"); // Sans le buffer on ne peut rien faire exit(1); } printf(" [OK]"); fprintf(hist, " [OK]"); // Initialisation du tableau des threads printf("\n Initialisation du tableau d'id de thread ... "); fprintf(hist, "\n Initialisation du tableau d'id de thread ... "); for (i = 0; i < 4; i++) { th_occupe[i] = -1; } printf(" [OK]"); fprintf(hist, " [OK]"); // Initialisation num_libre a 0 num_libre = 0; // creation du socket fprintf(hist, "\n Creation de socket sur le port %d... ",atoi(argv[1])); printf("\n Creation de socket sur le port %d... ",atoi(argv[1])); serveur = cree_socket(atoi(argv[1]),hist); if(serveur == -1) { printf(" [FAILED]\n"); exit(1); } printf(" [OK]\n"); fprintf(hist, " Fixer la file d'attente par 5 ... "); printf(" Fixer la file d'attente par 5 ... "); if(listen(serveur, 5) == -1) { printf(" [FAILED]\n"); fprintf(hist, " [FAILED]\n"); perror("Cause"); exit(1); } printf(" [OK]\n"); fprintf(hist, " [OK]\n"); printf("\n \t Le serveur va entre dans une boucle infini \n"); printf(" \t ========================================= "); freopen("/historique","a+",hist); //////////////////////////////////////////////////////////// // Boucle de gestion des connexions // /////////////////////////////////////////////////////////// while(vrai) { fflush(stdout);//vidage de la sortie standard printf("\n \t Attente des demandes de connexion "); printf("\n"); // Le serveur attend une demande de connexion fprintf(hist, "\n Attente de demande de connexion ... "); long_client = sizeof(client); nouv_sock = accept(serveur,(struct sockaddr *) &client,&long_client); if(nouv_sock < 0) { fprintf(hist, " [FAILED]\n"); perror("Cause"); continue ; // On neglige la requete } fprintf(hist, " [OK]"); // On doit recupere les informations du client // qui a demande une connexion printf("\n %s:%u demande la connexion au serveur ...", inet_ntoa(client.sin_addr),ntohs(client.sin_port)); fprintf(hist, "\n Une demande de connexion est recue:\n"); fprintf(hist, " _==================================_\n"); fprintf(hist, "\t * Famille du Socket client: %x\n", ntohs(client.sin_family)); fprintf(hist, "\t * Port client: %u\n", ntohs(client.sin_port)); fprintf(hist, "\t * IP client: %s\n", inet_ntoa(client.sin_addr)); if(num_libre > 3) { strcpy(buf,"NO"); long_buf = strlen("NO") + 1; fprintf(hist, "\n Le serveur va envoye un refus de connexion ..."); envoye = send(nouv_sock , buf , long_buf , 0); if(envoye < 0) { fprintf(hist, " [FAILED]\n"); perror("Cause"); continue ; } printf(" [OK]\n"); printf("\n Connexion du %s:%u refuse: depacement de capacite \n", inet_ntoa(client.sin_addr),ntohs(client.sin_port)); fprintf(hist, " [OK]\n"); fprintf(hist,"\n|**************************************************|"); fprintf(hist,"\n| DEPACEMENT DE CAPACITE DU SERVEUR |"); fprintf(hist, "\n| Connexion du client %s refuse |", inet_ntoa(client.sin_addr)); fprintf(hist,"\n|**************************************************|"); } else { strcpy(buf,"OK"); long_buf = strlen("OK") + 1; fprintf(hist, " Le serveur envoi une acceptation de connexion ... "); envoye = send(nouv_sock,buf,long_buf,0); if(envoye < 0) { fprintf(hist," [FAILED]\n"); perror("Cause"); continue; } fprintf(hist, " [OK]\n"); num_libre ++; // On cherche un identificateur libre for(i = 0; i < 4; i++) if(th_occupe[i] == -1) { // La structure special contient le nom de fichier // la chaine a recherche // et l'adresse du client // creation du thread associe au client fprintf(hist, "\n Creation de thread ... "); special.addr = client; special.desc = nouv_sock; if( pthread_create(&th_id[i], NULL,(void *) th_trait, (void *)&special) != 0 ) { fprintf(hist, " [FAILED]\n"); exit(1); } th_occupe[i] = th_id[i]; break; } } freopen("/historique","a+",hist); }// while(true) }
void * th_trait(void *client_addr) { // Descripteur de fichier // utilise par fopen pour la lecture de fichier // cherche dans le cas ou il existe FILE *df; // Descripteur de fichier log pour chaque thread FILE *log; char nom_log[MAX_BUF]; // Descripteur du socket serveur // car chaque thread va avoir un numero de port // speciale pour communiquer avec sont client // ceci n'est pas necessaire dans le mode connecte // puisque accepet retourne un identificateur nouveau // pour chaque demande de connexion int serveur; // longuer de la structure sockaddr client int long_client; // utilise pour recuperer les valeurs de retour // des fonctions recvfrom et sendto int envoye, recue; // Tampon de lecture ecriture char *buf; // Pour specifie la longueur du bufer int long_buf; // Stocke le nom de fichier envoye par le client char nom_fichier[MAX_REP_CHEMIN]; // Stocke le chemin d'acce au fichier // retourne par la fonction recherche_fichier char chemin[MAX_REP_CHEMIN]; // Stocke la chaine a cherche dans le fichier char motif[MAX_BUF]; // ndice indiquant si le motif a ete trouve ou pas int motif_trouve = -1; // Pour le parcour du tableau de thread int i; // Pour compter le nombre des bloque envoye au client; int num_bloc = 0; // Utilise pour savoir la longueur lu par la fct read int long_lu=0; struct sockaddr_in *client = (struct sockaddr_in *)client_addr; // Pour obtenir le repertoire courant du travail char rtc[MAX_REP_CHEMIN]; // Creation de thread reussi sprintf(nom_log,"/serveur%s:%u.log", inet_ntoa(client->sin_addr),ntohs(client->sin_port)); printf("\n -> Pour les details de transfert voir le fichier: %s", nom_log); log = fopen(nom_log ,"w+"); if(log == NULL) { printf("\n Erreur d'ouverture du fichier log.\n"); perror("Cause"); pthread_exit(1); } fprintf(log," -----------------------------------------------------\n"); fprintf(log,"| Fichier log generer automatiquement par le serveur |"); fprintf(log,"\n -----------------------------------------------------\n"); fprintf(log, "\n Le thread %d va s'occupe de la demande du client %s\n", pthread_self(),inet_ntoa(client->sin_addr)); // Essayer d'allouer le buffer buf = (char *)malloc(MAX_BUF); if (buf == NULL) { fprintf(log,"\n Impossible d'alloue le buffer.\n", pthread_self()); fprintf (log, "\n Arret du trait associe su client %s:%u \n", inet_ntoa(client->sin_addr), ntohs(client->sin_port) ); fclose(log); section_critique(log); pthread_exit(1); } long_buf = MAX_BUF; long_client = sizeof(client); // Creation de socket pour le thread fprintf(log, " Creation de socket ... ",pthread_self()); // Creation d'un nouveau socket pour chaque thread // avec un numero de port = num_port_client + 1 serveur = cree_socket(ntohs(client->sin_port)+1, log); if(serveur < 0) { fclose(log); section_critique(log); pthread_exit(1); } // Attente de messages des clients // On attend un nom de fichier a cherhe fprintf(log, "\n Attente du nom de fichier a cherche ... ", pthread_self()); memset(buf,0,strlen(buf)); recue = recvfrom( serveur, buf, long_buf , 0, (struct sockaddr*)client, &long_client ); if (recue < 0) { fprintf(log, " [FAILED]"); perror("Cause"); fclose(log); close(serveur); section_critique(log); pthread_exit(1); } fprintf(log, " [OK]"); strcpy(nom_fichier,buf); fprintf(log, "\n Le fichier cherche est: %s", nom_fichier); // On attend la motif a cherche dans le fichier fprintf(log, "\n Attente du motif a cherche ... ",pthread_self()); memset(buf,0,strlen(buf)); recue = recvfrom( serveur, buf, long_buf , 0, (struct sockaddr*)client, &long_client ); if (recue < 0) { fprintf(log," [FAILED]\n"); perror("Cause"); fclose(log); close(serveur); section_critique(log); pthread_exit(1); } strcpy(motif, buf); fprintf(log, " [OK]"); fprintf(log, " \n Le motif cherche est: %s", motif); // Recherche du fichier et recuperation de sont chemin // dans le cas ou il existe fprintf(log, "\n Recherche du fichier %s ... ",nom_fichier); memset(chemin,0,strlen(chemin)); strcpy(chemin,cherche_fichier(nom_fichier,log)); if(!strcmp(chemin,"NO_EXIST")) { fprintf(log, "\n Le fichier cherche n'existe pas ... "); // On envoi un message pour prevenir le client // que le fichier qu'il a demande n'existe pas // dans le serveur fprintf(log, "\n Envoyer 'NO_EXIST' au client ... "); strcpy(buf,"NO_EXIST"); long_buf = strlen("NO_EXIST") + 1; envoye = sendto(serveur,buf,long_buf,0, (struct sockaddr *)client, long_client); if(envoye < 0) { fprintf(log," [FAILED]"); perror("Cause"); } fprintf(log," [OK]"); close(serveur); fclose(log); section_critique(log); pthread_exit(1); } // Si on est arrive ici, ca veut dir que le fichier existe fprintf(log,"\n Le fichier existe et sont chemin est: %s\n",chemin); printf("\n Le fichier existe et sont chemin est: %s\n",chemin); fprintf(log, "\n Envoyer 'EXIST' au client ... "); strcpy(buf,"EXIST"); long_buf = strlen("EXIST") + 1; envoye = sendto(serveur,buf,long_buf,0, (struct sockaddr *)client, long_client); if(envoye < 0) { perror("Cause"); close(serveur); fclose(log); section_critique(log); pthread_exit(1); } // On ouvre le fichier pour lecture // la fonction fopen nous retourne un descripteur // qui va etre utilise par la fonction fscanf; fprintf(log, "\n Debut de transfert:"); fprintf(log, "\n ___________________"); df = fopen(chemin,"r+"); if(df != NULL) { // Tanque fin de fichier non atteinte on envoi un bloque de donne de taille // strlen(buf) au client qui possede l'adresse client while(!feof(df)) { num_bloc ++; if((long_lu = fread(buf,1,MAX_BUF,df)) < 0) { fprintf(log, "\n Erreur de lecture de fichier.\n"); perror("Cause"); break; } buf[long_lu] = '\0'; // La recherche du motif dans le buffer courant if(strstr(buf, motif)) { motif_trouve = num_bloc; } fprintf(log,"\n Lecture d'un bloque avec succe."); do { fprintf(log, "\n\t Envoi du bloc N %d ",num_bloc); long_buf = strlen(buf)+1; envoye = sendto( serveur,buf, long_buf, 0, (struct sockaddr *)client, long_client ); if(envoye < 0) { fprintf(log, "\n Erreur d'envoi de donne. \n"); perror("Cause"); continue; } fprintf(log,"\n\t Les donnees on ete envoyees avec succe."); fprintf(log, "\n Attente de validation par le client ... "); memset(buf,0,strlen(buf)); recue = recvfrom(serveur, buf, long_buf,0, (struct sockaddr *)client, &long_client); if(recue < 0) { fprintf(log," [FAILED]"); continue; } fprintf(log," [OK]"); if (!strcmp(buf,"OK")) { fprintf(log, "\n Le bloque N %d a ete recue par le client avec succe.",num_bloc); break; } else if(!strcmp(buf,"NO")) { fprintf(log, "\n Le client a demande la retransmission du bloc N %d", num_bloc); continue; } }while (vrai); /* do d'envoi de bloc*/ } /* while(!feof(df))*/ } /*if(df != NULL)*/ else { fprintf(log, "\n Un probleme est survennu lors de l'ouverture du fichier."); perror("Cause"); strcpy(buf,"$ERREUR$"); long_buf = strlen(buf); sendto(serveur, (char *) buf, long_buf, 0, (struct sockaddr *)client, long_client); fclose(log); close(serveur); section_critique(log); pthread_exit(1); } strcpy(buf, "$FIN$"); long_buf = strlen(buf) + 1; fprintf(log,"\n Envoye $FIN$ au client %s:%u ... ", inet_ntoa(client->sin_addr), ntohs(client->sin_port)); envoye = sendto(serveur, (char *) buf, long_buf, 0, (struct sockaddr *)client, long_client); if(envoye < 0) { printf(" [FAILED]"); fprintf(log, " [FAILED]"); perror("CAUSE"); } else { fprintf(log, " [OK]"); printf("\n Envoi du fichier a ete termine avec succe"); fprintf(log, "\n\t\t ------------------------ "); fprintf(log, "\n\t\t |Envoi du fichier termine| "); fprintf(log, "\n\t\t ------------------------ "); fprintf(log,"\n Envoyer la reponse indiquant si le motif a ete trouve ..."); if(motif_trouve >= 0) { memset(buf,0,MAX_BUF); // Le serveur renvoi une reponse indiquant le numero de bloque // qui contient la premiere occurence du motif cherche sprintf(buf,"\n Le motif cherche existe dans le bloc %d:",motif_trouve); long_buf = strlen(buf) + 1; } else { sprintf(buf,"\n Le motif cherche n'existe pas dans le fichier."); long_buf = strlen(buf) + 1; long_buf = strlen("\n Le motif n'existe pas dans le fichier.") + 1; } envoye = sendto(serveur, (char *) buf, long_buf, 0, (struct sockaddr *)client, long_client); if(envoye < 0) { fprintf(log, " [FAILED]"); } else { fprintf(log, " [OK]"); fprintf(log,"%s",buf); // Le motif existe ou n'existe pas fprintf(log, " \n Reponse concernant le motif ... "); recue = recvfrom(serveur, (char *) buf, long_buf, 0, (struct sockaddr *)client, &long_client); if(recue < 0) { fprintf(log, " [FAILED]"); perror("CAUSE"); } else { fprintf(log, " [OK]"); printf( "\n La requete du client %s:%u a ete traite avec succe.", inet_ntoa(client->sin_addr), ntohs(client->sin_port)); fprintf(log, "\n La requete du client %s:%u a ete traite avec succe.", inet_ntoa(client->sin_addr), ntohs(client->sin_port)); } } } fclose(log); fclose(df); close(serveur); section_critique(log); return NULL; }
int main(int argc, char **argv) { // Buffer pour la lecture et l'ecriture dans le socket char *buf; int long_buf; //Descripteur du client int client; // Utilise par sendto pour garder la valeur de retour int envoye; // Guarde la valeur de retour de la fonction recvfrom int recue; // Pour la construction de l'adresse du serveur struct sockaddr_in serveur; int long_serveur; // Utilise pour la resolution des non des domaine (DNS) // Conversion entre nom_machine->adresse_ip struct hostent *h; // Variable indiquant qu'on a atteint la fin de fichoer int fin = faux; struct in_addr *addr_ip_serv; printf("\n Verfication des arguments de la ligne de commande ... "); if (argc != 3) { printf(" [FAILED]"); printf("\n Usage: client nom_serveur num_proto\n"); exit(1); } printf(" [OK]"); // creation du socket printf(" \n Creation du socket ... "); client = cree_socket(atoi(argv[2])); if(client < 0) { perror("Cause"); exit(1); } // Allocation du buffer printf(" \n Allocation du buffer ... "); buf = (char *)malloc(MAX_BUF); if(buf == NULL) { printf(" [FAILED]\n"); perror("Cause"); exit(1); } printf(" [OK]\n"); // Le client envoi une demande de connexion long_buf = strlen("connect"); strcpy(buf,"connect"); // On construit l'adresse du serveur printf("\n Construction de l'adresse du serveur ... "); serveur.sin_family = AF_INET; serveur.sin_port = htons(SERV_PORT); printf(" [OK]"); printf("\n Resolution du nom de serveur %s ... ", argv[1]); h = gethostbyname(argv[1]); if (h == NULL) { printf(" [FAILED]\n"); perror("Cause"); exit(1); } printf(" [OK]\n"); addr_ip_serv = (struct in_addr *)h->h_addr_list[0]; printf("\n Adresse ip du serveur est: %s", inet_ntoa(*addr_ip_serv)); memcpy((char*)(&serveur.sin_addr.s_addr), h->h_addr_list[0], h->h_length); long_serveur = sizeof(serveur); // On va envoye une demande de connexion au serveur // notre protocole consiste a envoye un message contenant // la chaine de caractere "connect" // ceci n'est pas necessaire en mode connecte // car c'est la fonction connect qui assure cette tache printf("\n Demande de connexion au serveur ... "); envoye = sendto(client, buf, long_buf , 0, (struct sockaddr *)&serveur, long_serveur); if (envoye < 0) { printf(" [FAILED]"); perror("Cause"); // S'il y a une erreur de reception en arrete tout exit(1); } printf(" [OK]"); printf("\n Attente de validation ou refus de connexion ... "); memset(buf,0,strlen(buf)); recue = recvfrom(client, buf, long_buf, 0, (struct sockaddr *)&serveur, &long_serveur); if (recue < 0) { printf(" [FAILED]"); perror("Cause:"); exit(1); } if(strcmp(buf,"OK") != 0 && strcmp(buf,"NO") != 0) { printf(" [OK] \n"); printf("\n Attendu OK ou NO recue %s.\n", buf); exit(1); } if(strcmp(buf,"NO") == 0) { printf(" [FAILED]"); printf("\n\t\t !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! "); printf("\n\t\t !!! Le serveur est charge !!! "); printf("\n\t\t !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! \n"); close(client); exit(1); } if(strcmp(buf,"OK") == 0) { printf(" [OK]"); printf("\n\t\t ***************************************"); printf("\n\t\t *** Le serveur a accepte la demande ***"); printf("\n\t\t ***************************************"); } // Changement du port du serveur // pour devenir celui du thread associe serveur.sin_port = htons(atoi(argv[2])+1); // On envoi le nom de fichier a cherche printf("\n Entrer le nom de fichier a cherche: "); scanf("%s",buf); long_buf = strlen(buf) + 1; sprintf(nom_fich_recu, "copie_de_%s",buf); printf("\n Envoi du nom de fichier ... "); envoye = sendto(client, buf, long_buf , 0, (struct sockaddr *)&serveur, long_serveur); if(envoye < 0) { printf(" [FAILED]"); perror("Cause"); close(client); exit(1); } printf(" [OK]"); // On envoi la chaine a recherche dans le fichier printf("\n Entrer le motif a cherche: "); memset(buf,0,strlen(buf)); scanf("%s",buf); long_buf = strlen(buf); printf("\n Envoi du motif ... "); envoye = sendto(client, buf, long_buf , 0, (struct sockaddr *)&serveur, long_serveur); if(envoye < 0) { printf(" [FAILED]\n"); perror("Cause"); close(client); exit(1); } printf(" [OK]"); // Reception de la reponse pour l'existence du fichier printf("\n Attente de la reponse d'existance du fichier ..."); memset(buf,0,strlen(buf)); long_buf = MAX_BUF; recue = recvfrom(client, buf, long_buf, 0, (struct sockaddr *)&serveur, &long_serveur); if (recue < 0) { printf(" [FAILED]"); perror("Cause"); close(client); exit(1); } printf(" [OK]"); if(!strcmp(buf,"EXIST")) { printf("\n Le serveur a trouve le fichier cherche. \n"); } else if(!strcmp(buf,"NO_EXIST")) { printf("\n Le serveur n'a pas reussi a trouve le fichier.\n"); close(client); exit(1); } else { printf(" \n Attendu 'EXIST' ou 'NO_EXIST': Recue %s \n",buf); close(client); exit(0); } fd = fopen(nom_fich_recu,"w+"); printf("\n **************************************************************** "); printf("\n * Reception du contenu * "); printf("\n **************************************************************** \n"); long_buf = MAX_BUF; if(fd == NULL) { printf("\n Impossible de cree un fichier pour la reception des donnees recu"); perror("Cause"); close(client); exit(1); } else do /* tanque non fin de fichier */ { num_bloc ++; do /* Tanque un bloque n'a pas ete recue */ { printf("\n - Attente du bloque de donnee N%d... ",num_bloc); // Effacer le contenu du buffer long_buf = MAX_BUF; memset(buf,0,MAX_BUF); recue = recvfrom(client, buf, long_buf, 0, (struct sockaddr *)&serveur, &long_serveur); if(recue < 0) { printf(" [FAILED]\n"); printf("\n Erreur lors de la reception des donnees. \n"); perror("Cause"); strcpy(buf,"NO"); long_buf = strlen("NO")+1; printf("\n Envoye une demande de retransmission ... "); envoye = sendto(client, buf, long_buf, 0, (struct sockaddr *)&serveur, long_serveur); if(envoye < 0) { printf(" [FAILED]"); perror("Cause"); printf("\n Il y a eu une erreur lors de la reception du bloque "); printf("\n et une erreur lors de la demande de retransmission. "); printf("\n Par consquent le bloque envoye par le serveur est sera perdu. "); break; // Puisque on a pas pu prevenir le serveur qu'il y eu une erreur // on evite le bloque actuel et en previent le client qu'il y a // une perte de donnees } printf(" [OK]"); continue; } /* if recue < 0 */ printf(" [OK]"); break; // Cassage de la boucle de retransmission }while(vrai); /* Reception du bloque */ if(!strcmp(buf,"$FIN$") || !strcmp(buf, "$ERREUR$")) fin = vrai; // Ecrire les donnees recu dans le fichier qui porte comme nom // client-num_port if(fin == faux) // Car $FIN$, $ERREUR$ ne font pas partie du fichier transferer if(fprintf(fd,"%s",buf) < 0) { printf("\n Erreur d'ecriture dans le fichier de reception. \n"); perror("Cause"); exit(1); } // On previent le serveur que le bloque qu'il a envoye // a ete recue avec succe en lui envoyant un OK strcpy(buf,"OK"); long_buf = strlen("OK")+1; printf("\n * Envoye un 'OK' au serveur ... "); envoye = sendto(client, buf, long_buf,0, (struct sockaddr *)&serveur, long_serveur); if(envoye < 0) { printf(" [FAILED]"); perror("Cause"); continue; } printf(" [OK]"); }while(fin == faux); /* !feof(df) */ // On attend la reponse concernant le motif // printf("\n Attente de la recpetion concernant le motif ... "); long_buf = MAX_BUF; memset(buf,0,MAX_BUF); recue = recvfrom(client, buf, long_buf, 0, (struct sockaddr *)&serveur,&long_serveur); if(recue < 0) { printf(" [FAILED]"); perror("Cause"); } else { printf(" [OK]"); printf(" %s",buf); printf("\n Envoye un OK au serveur ... "); strcpy(buf,"OK"); long_buf = strlen(buf) +1; envoye = sendto(client, buf, long_buf,0, (struct sockaddr *)&serveur, long_serveur); if(envoye < 0) { printf(" [FAILED]"); perror("Cause"); } printf(" [OK]"); printf(" \n Le transfert est termine avec succe."); printf(" \n Ouvrir le fichier %s pour voir le resultat de la recpetion.", nom_fich_recu); } fclose(fd); close(client); printf("\n"); return 0; }