Tengo preguntas sobre cómo cerrar correctamente el descriptor de archivo de socket. Supongamos que el servidor bifurca otro procedimiento cada vez que acepta una nueva conexión. El descriptor de archivo de socket original es sockfd y el nuevo descriptor de archivo de socket es new_sockfd .
sockfd = socket(...) bind(...); listen(...); while(1) { new_sockfd = accept(...); if(fork() == 0) { // Child process dosomething(...); } else { } } Mi pregunta es dónde debemos poner close(sockfd) y close(new_sockfd) . He visto algunos ejemplos en el sitio web ( http://www.tutorialspoint.com/unix_sockets/socket_quick_guide.htm "Manejar conexión múltiple") colocan close(sockfd) dentro del bloque if y close(new_sockfd) en el bloque else . Pero, después de la bifurcación, ¿no se ejecutan los dos procesos en paralelo? Si el proceso principal cierra new_sockfd , ¿no afectará al proceso secundario para manejar el socket? Además, si el proceso secundario ejecuta close(sockfd) , ¿no afectará esto a todo el programa de socket?
Cuando un proceso se bifurca, los descriptores de archivo se duplican en el proceso secundario. Sin embargo, estos descriptores de archivo son distintos entre sí. Cerrar un descriptor de archivo en el elemento secundario no afecta al descriptor de archivo correspondiente en el elemento principal, y viceversa.
En su caso, dado que el proceso hijo necesita el socket aceptado new_sockfd y el proceso padre continúa usando el socket de escucha sockfd , el hijo debería close(sockfd) (en su bloque if ; esto no afecta al padre) y el padre debería close(new_sockfd) (en su bloque else ; esto no afecta al niño). El hecho de que el padre y el hijo se estén ejecutando al mismo tiempo no afecta esto.
El padre debe cerrar el socket aceptado (en el bloque else ): permanece abierto en el proceso hijo hasta que el hijo termine con él, momento en el que debe emitir su propio cierre.