/* AMELIORATION de rebours-s */ /* utilisation de la primitive fork */ /* afin de lancer des fils en concurrence */ /* traitant les requêtes des clients */ /* ainsi ces derniers ne sont plus bloqués */ /* lancer rebours2-s numero_port */ /* lance un serveur en ecoute sur le port numero_port */ /* pour tester faire telnet adr_ip_serv numero_port */ #include #include #include #include #include #include #include #include /* taille maximale pour le nom d'une machine */ #define MAXNAME 256 void finfils(int sig) { /* on traite la fin des fils en attente de façon non blocante */ while (waitpid(-1,NULL,WNOHANG) >0) ; } int main(int argc, char *argv[]) { char nom[MAXNAME], chaine[MAXNAME]; int numport, sd, sclient; struct sockaddr_in sa; struct hostent *infos; int pid, j; numport = atoi(argv[1]); /* on récupère le nom de la machine ou le prog est lancé */ gethostname(nom,MAXNAME); /* on récupère alors son adresse ip */ infos = gethostbyname(nom); /* mise en place d'un tube de communication réseau */ sd = socket(AF_INET,SOCK_STREAM,0); /* préparation des données nécessaires à la configuration du tube */ memset(&sa,0,sizeof(sa)); sa.sin_family = AF_INET; /* numéro du port de communication */ /* transformé en notation réseau */ /* pour éviter les problèmes big endian, little endian */ sa.sin_port = htons(numport); /* adresse ip du serveur */ sa.sin_addr.s_addr = *((unsigned long int *)(infos -> h_addr)); /* configuration du tube avec les données précédentes */ bind(sd,(struct sockaddr *)&sa,sizeof(sa)); /* écoute sur le tube, max 10 clients */ listen(sd,10); /* pour récupérer le signal des fils quand ils ont terminé */ signal(SIGCHLD,finfils); while (1) { /* accepter une connexion sans récupérer les paramètres du client */ /* créé un nouveau tube pour traiter la demande */ /* le tube initial est de nouveau en attente sur le port */ sclient = accept(sd,NULL,NULL); pid = fork(); if (pid == 0) { close(sd); /* envoi de données dans le tube */ for (j = 5; j >=0; j--) { sprintf(chaine,"%d\n",j); write(sclient,chaine,strlen(chaine)); sleep(1); } /* fermeture du tube temporaire */ close(sclient); /* force la terminaison du fils, sinon création */ /* d'un nombre illimité de processus fils => effondrement de la machine */ exit(0); } else close(sclient); } /* fermeture du serveur */ close(sd); }