c - Problem with select when closing socket -


i'm doing multiclient server accepts connection, forks, , gives connection child can handle it. it's multiclient server, has multiple children.

the main process in infinite while makes select find out if there new incoming connection or if child trying communicate.

the problem arises when close client (which connected son of main server): randomly happens client connection closed, , select gets unblocked because supposedly internal socket (which handles incoming connection between children , main server) modified, far concerned not true. happened client closed connection , child died.

can give me clue of it's going on here? i'm quite lost.

this code of infinite loop in main server:

while (1) {     /*inicializo variables para el select*/     sflag = 0;     fd_zero(&readfds);     fd_set(sockfd, &readfds);     fd_set(sockifd,&readfds);     max = (sockfd > sockifd) ? sockfd : sockifd;     for(aux = isockets; aux != null; aux = aux -> next){         fd_set(aux -> sd, &readfds);         max = (max > aux -> sd) ? max : aux -> sd;     }      printf("pre-select\n");     select(max + 1, &readfds, null, null, null);     /*checkeo si salio por actividad en un socket interno*/     (aux = isockets; aux != null; aux = aux -> next){         if (fd_isset(aux -> sd, &readfds)){             printf("comunicacion con el socket: %d\n", aux -> sd);             sflag = 1;             actsocket = aux -> sd;             break;         }     }     if (sflag == 1){//mensaje de un hijo         n = recv(actsocket, buffer, sizeof(buffer), 0);         if (n == 0) {             printf("conexion cerrada con el socket interno: %d\n", actsocket);             close(actsocket);             isockets = free_sock(isockets, actsocket);             printf("isockets: %p\n", isockets);         }         else if(n < 0) error ("error en comunicacion interna");         else printf("mensaje del boludon: %s\n", buffer);     }        else if (fd_isset(sockifd, &readfds)){// un hijo inicia conexion interna         printf("antes de accpet interno\n");         newisockfd = accept(sockifd, (struct sockaddr *) &ucli_addr, &uclilen);         printf("nueva conexion interna, socketfd: %d\n", newisockfd);         isockets = add_socket(isockets,newisockfd, 0);         recorre(isockets);         if (newisockfd < 0) error ("error en accept unix, padre");     }     else if (fd_isset (sockfd, &readfds)){/*conexion entrante*/         printf("conexion entrante\n");         newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr, &clilen);             if (newsockfd < 0) error("error on accept");             pid = fork();          if (pid < 0) error("error on fork");             if (pid == 0){//hijo                     close(sockfd);             dostuff(newsockfd, path, tm,fd[0]);                     exit(0);              }             else {  //padre             printf("conexion aceptada, pid hijo %d\n", pid);             close(newsockfd);         }     }     } 

so, randomly, when close connection, select unblock if "sockifd" modified, wasn't. don't know why doing that.

one thing wrong in code you're not checking return value of select.

if select interrupted signal (returns -1 errno = eintr, example sigchld if 1 of children died), contents of &readfds undefined, , must not read. (see example linux man page select.)

so check return value if select, , loop right without going through &readfds processing if there's temporary error eintr.


Comments

Popular posts from this blog

linux - Using a Cron Job to check if my mod_wsgi / apache server is running and restart -

actionscript 3 - TweenLite does not work with object -

jQuery Ajax Render Fragments OR Whole Page -