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; }
void * th_trait(void *special) { // Descipteur de la socket bidirectionnelle // retourne par accept int serveur; // 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]; // 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 bloc envoye au client; int num_bloc = 0; // Utilise pour savoir la longueur lu par la fct read int long_lu=0; // Pour recevoir l'arguemt specail qui contient // l'adresse du client et le descripteur de la socket comp *spec = (comp *)special; struct sockaddr_in *client = (struct sockaddr_in *)&spec->addr; serveur = (int)spec->desc; memset(nom_log,0,MAX_BUF); sprintf(nom_log,"serveur-%s-%d.log", inet_ntoa(client->sin_addr),pthread_self()); log = fopen(nom_log ,"w+"); if(log == NULL) { printf("\n Erreur d'ouverture du fichier log.\n"); 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); // Attente de messages des clients // On attend un nom de fichier a chercher fprintf(log, "\n Attente du nom de fichier a cherche ... ", pthread_self()); memset(buf,0,strlen(buf)); recue = recv(serveur, buf, long_buf , 0); 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); // 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 = recv(serveur, buf, long_buf , 0); 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]"); // 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, " [FAILED]\n"); fprintf(log, "\n Le fichier cherche n'existe pas. \n "); // 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 = send(serveur,buf,long_buf,0); 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); fprintf(log, "\n Envoyer 'EXIST' au client ... "); strcpy(buf,"EXIST"); long_buf = strlen("EXIST") + 1; envoye = send(serveur,buf,long_buf,0); 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; df = fopen(chemin,"r+"); if(df != NULL) { // Tant que fin de fichier non atteinte on envoi un bloc 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'; fprintf(log,"\n Lecture d'un bloc avec succès."); // La recherche du motif dans le buffer courant if(strstr(buf, motif)) { motif_trouve = num_bloc; } fprintf(log, "\n\t*********** Envoi du bloc N %d ************",num_bloc); long_buf = strlen(buf)+1; envoye = send(serveur,buf, long_buf, 0); if(envoye < 0) { fprintf(log, "\n Erreur d'envoi de donne. \n"); perror("Cause"); continue; } fprintf(log,"\n Les donnees on ete envoyees avec succès."); } /* 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); send(serveur, (char *) buf, long_buf, 0); fclose(df); fclose(log); close(serveur); section_critique(log); pthread_exit(1); } strcpy(buf, "$FIN$"); long_buf = strlen(buf) + 1; printf(" \n Envoye $FIN$ au client %s:%u ... ", inet_ntoa(client->sin_addr), ntohs(client->sin_port)); fprintf(log,"\n Envoye $FIN$ au client %s:%u ... ", inet_ntoa(client->sin_addr), ntohs(client->sin_port)); envoye = send(serveur, (char *) buf, long_buf, 0); if(envoye < 0) { printf(" [FAILED]"); fprintf(log, " [FAILED]"); perror("CAUSE"); } else { fprintf(log, " [OK]"); printf("\n Envoi du fichier terminé avec succès"); fprintf(log, "\n ------------------------ "); fprintf(log, "\n |Envoi du fichier termine| "); fprintf(log, "\n ------------------------ "); fprintf(log,"\n Envoyer la reponse indiquant si le motif a ete trouve ..."); if(motif_trouve >= 0) { memset(buf,0,MAX_BUF); // Le serveur renvoie une reponse indiquant le numero de bloc // 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 = send(serveur, buf, long_buf, 0); if(envoye < 0) { fprintf(log, " [FAILED]"); } else { fprintf(log, " [OK]"); printf( "\n La requete du client %s:%u a ete traite avec succès.", inet_ntoa(client->sin_addr), ntohs(client->sin_port)); fprintf(log, "\n La requete du client %s:%u a ete traite avec succès.", inet_ntoa(client->sin_addr), ntohs(client->sin_port)); } } fclose(log); fclose(df); close(serveur); section_critique(log); return NULL; }