Я делаю многоклиентный сервер, который принимает соединение, разветвляется и передает соединение дочернему элементу, чтобы он мог его обработать.Это многоклиентный сервер, поэтому он имеет несколько дочерних элементов.
Основной процесс находится в бесконечном while
, что составляет select
, чтобы выяснить, существует ли новое входящее соединение или если ребенок пытаетсяобщаться.
Проблема возникает, когда я закрываю клиента (который подключен к сыну основного сервера): случайным образом случается, что клиентское соединение закрывается, и селектор разблокируется, потому что предположительно внутренний сокет (который обрабатывает входящее соединение между дочерним и основным сервером), но, насколько мне известно, это не так.На самом деле произошло то, что клиент закрыл соединение, а ребенок только что умер.
Может кто-нибудь подсказать мне, что здесь происходит?Я совсем растерялся.
Это код бесконечного цикла на главном сервере:
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*/
for (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);
}
}
}
Так, случайно, когда я закрываю соединение, выберите разблокировать как будто "sockifd "был изменен, но это не так.Не знаю, зачем это делает.