Mam pytania dotyczące prawidłowego zamykania deskryptora pliku gniazda. Załóżmy, że serwer podaje inną procedurę za każdym razem, gdy akceptuje nowe połączenie. Oryginalny deskryptor pliku gniazda to sockfd
, a nowy deskryptor pliku gniazda to new_sockfd
.Jak prawidłowo używać gniazda zbliżonego do widelca?
sockfd = socket(...)
bind(...);
listen(...);
while(1) {
new_sockfd = accept(...);
if(fork() == 0) {
// Child process
dosomething(...);
}
else {
}
}
Moje pytanie brzmi, gdzie powinniśmy umieścić close(sockfd)
i close(new_sockfd)
. Widziałem kilka przykładów na stronie internetowej (http://www.tutorialspoint.com/unix_sockets/socket_quick_guide.htm "Obsługa wielu połączeń") umieszczają close(sockfd)
w bloku if
i close(new_sockfd)
w bloku else
. Ale po rozwidleniu nie są dwa procesy działające równolegle? Jeśli proces nadrzędny zakończy się new_sockfd
, czy nie wpłynie to na proces potomny obsługi tego gniazda? Ponadto, jeśli proces potomny wykonuje close(sockfd)
, czy nie wpłynie to na cały program gniazda?
@JosephMyers To nie jest poprawne. Deskryptor pliku jest odrębny w obu procesach. Rodzic powinien zamknąć akceptowane gniazdo: pozostaje otwarte w procesie potomnym. – EJP
@EJP Zamierzam zajrzeć do tego trochę więcej i być może wrócę ze szczegółami. Bardziej zaznajomiłem się z systemami BSD, które według mojego doświadczenia z programowaniem serwerów oraz procesów powłokowych i rozwidlających ogólnie zapewniały dokładniejszą kontrolę nad tym, czy deskryptory plików i powiązane zasoby zostały zduplikowane lub udostępnione. Dziękuję za poświęcenie czasu na komentarze i zachęcenie mnie do powtórzenia tego, co zapamiętałem z doświadczenia. –