Par rapport à la question n°1, il n'y a pas beaucoup de changement à faire. On conserve les procédures do_client() et send_to() ainsi que la fonction receive_from(). On change juste le code source de la boucle d'acquisition des connexions :
void sigchld_handler(int signo) { signal(SIGCHLD, sigchld_handler); while (waitpid(-1, NULL, WNOHANG) > 0); } int main() { int fd_srv, fd_con; struct sockaddr_in adr_srv, adr_cli; int err; socklen_t adr_cli_len; fd_srv = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); if (fd_srv<0) { printf("Erreur de creation de la socket !\n"); exit(1); } bzero(&adr_srv, sizeof(adr_srv)); adr_srv.sin_family = AF_INET; err = inet_aton("0.0.0.0", &adr_srv.sin_addr); if (err == 0) { printf("Adresse IPv4 invalide !\n"); exit(1); } adr_srv.sin_port = htons(8080); err = bind(fd_srv, (struct sockaddr *) &adr_srv, sizeof(adr_srv)); if (err != 0) { printf("Erreur d'accès au port serveur !\n"); exit(1); } err = listen(fd_srv, 5); if (err != 0) { printf("Erreur de création de la file d'attente !\n"); exit(1); } signal(SIGCHLD, sigchld_handler); printf("Serveur lancé !\n"); while(1) { adr_cli_len = sizeof(adr_cli); fd_con = accept(fd_srv, (struct sockaddr *) &adr_cli, &adr_cli_len); if (fd_con>=0) { printf("Connexion acceptée !\n"); if (fork()==0) { close(fd_srv); do_client(fd_con); close(fd_con); printf("Connexion fermée !\n"); exit(0); } close(fd_con); } } return 0; }
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <netdb.h> #include <sys/socket.h> #include <string.h> // pour la fonction bzero #include <arpa/inet.h> // pour la fonction inet_addr #include <unistd.h> // pour la fonction fork #include <signal.h> // pour la fonction signal #include <sys/wait.h> // pour la fonction waitpid void sigchld_handler(int signo) { signal(SIGCHLD, sigchld_handler); while (waitpid(-1, NULL, WNOHANG) > 0); } char* receive_from(int fd) { static char buf[2048]=""; static int pos=0; int len; char *ret; while (1) { for(len=0; len<pos ; len++) if(buf[len]=='\n') break; if(buf[len]=='\n') break; len=sizeof(buf)-pos-1; if (len==0) { shutdown(fd, SHUT_RDWR); return NULL; } len=read(fd,buf+pos,len); if (len==0) return NULL; pos+=len; } buf[len]=0x00; ret=(char*) malloc(len+1); memcpy(ret,buf,len+1); memcpy(buf,buf+len+1,sizeof(buf)-len-1); pos-=len+1; return(ret); } void send_to(int fd, char* buf) { int i; for (i=0;i<strlen(buf);i++) { write(fd,buf+i,1); usleep(200000); } write(fd,"\n",1); } void do_client(int fd) { char *buf; while (1) { buf=receive_from(fd); if (buf == NULL) break; send_to(fd,buf); free(buf); } } int main() { int fd_srv, fd_con; struct sockaddr_in adr_srv, adr_cli; int err; socklen_t adr_cli_len; fd_srv = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); if (fd_srv<0) { printf("Erreur de creation de la socket !\n"); exit(1); } bzero(&adr_srv, sizeof(adr_srv)); adr_srv.sin_family = AF_INET; err = inet_aton("0.0.0.0", &adr_srv.sin_addr); if (err == 0) { printf("Adresse IPv4 invalide !\n"); exit(1); } adr_srv.sin_port = htons(8080); err = bind(fd_srv, (struct sockaddr *) &adr_srv, sizeof(adr_srv)); if (err != 0) { printf("Erreur d'accès au port serveur !\n"); exit(1); } err = listen(fd_srv, 5); if (err != 0) { printf("Erreur de création de la file d'attente !\n"); exit(1); } signal(SIGCHLD, sigchld_handler); printf("Serveur lancé !\n"); while(1) { adr_cli_len = sizeof(adr_cli); fd_con = accept(fd_srv, (struct sockaddr *) &adr_cli, &adr_cli_len); if (fd_con>=0) { printf("Connexion acceptée !\n"); if (fork()==0) { close(fd_srv); do_client(fd_con); close(fd_con); printf("Connexion fermée !\n"); exit(0); } close(fd_con); } } return 0; }