Compared to question #1, there is not much change to be made. We keep the do_client() and send_to() procedures as well as the receive_from() function. We just change the source code of the connection acquisition loop:
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("Socket creation error!\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("Invalid IPv4 address!\n"); exit(1); } adr_srv.sin_port = htons(8080); err = bind(fd_srv, (struct sockaddr *) &adr_srv, sizeof(adr_srv)); if (err != 0) { printf("Server port access error!\n"); exit(1); } err = listen(fd_srv, 5); if (err != 0) { printf("Queue creation error!\n"); exit(1); } signal(SIGCHLD, sigchld_handler); printf("Server launched!\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("Connection accepted!\n"); if (fork()==0) { close(fd_srv); do_client(fd_con); close(fd_con); printf("Connection closed!\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> // for the function bzero #include <arpa/inet.h> // for the function inet_addr #include <unistd.h> // for the function fork #include <signal.h> // for the function signal #include <sys/wait.h> // for the function 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("Socket creation error!\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("Invalid IPv4 address!\n"); exit(1); } adr_srv.sin_port = htons(8080); err = bind(fd_srv, (struct sockaddr *) &adr_srv, sizeof(adr_srv)); if (err != 0) { printf("Server port access error!\n"); exit(1); } err = listen(fd_srv, 5); if (err != 0) { printf("Queue creation error!\n"); exit(1); } signal(SIGCHLD, sigchld_handler); printf("Server launched!\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("Connection accepted!\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; }