Допустим, вы пишете сервер и хотите, чтоб он мог обслуживать несколько клиентов. Один из вариантов решения этой задачи может заключаться в использовании вызова fork() и обслуживании запроса в форке. Код может быть примерно следующим:
Казазалось бы, что всё правильно - мы принимаем соединение, вызываем fork() и в ребёнке отправляем обрабатываться принятое соединение, а сами ждём следующее соединение. Но вот тут кроется одна маленькая неочиведность - закрытие сокета в ребёнке на самом деле не закрое сокет. Всё дело в том, что после вызова fork(), пораждается новый процесс у которого есть свой дескриптор на этот сокет. То есть на один и тот же сокет мы имеем 2 дескриптора: один в родителе, другой в ребёнке. Когда функция server() отработает и закроет сокет, то останется ещё один дескриптор(который в родителе) и сокет на самом деле не закроется. Чтоб сокет закрывался на самом деле, его нужно закрывать в обоих процессах.
Теперь сокет будет закрываться в родителе сразу же и останется всего один дескриптор - в ребёнке. Когда ребёнок закроет свой сокет, то на сокет не останется ни одного дескриптора и сокет будет закрыт по-настоящему.
Код:
int forkResult = 0;
int aSocket = 0;
do{
aSocket = accept(listener, NULL, NULL);
forkResult = fork();
switch(forkResult){
case -1:{
printf("fork() err\n");
break;
}
case 0:{
server(aSocket);
break;
}
}
}while(forkResult>0);
Код:
int forkResult = 0;
int aSocket = 0;
do{
aSocket = accept(listener, NULL, NULL);
forkResult = fork();
switch(forkResult){
case -1:{
printf("fork() err\n");
break;
}
case 0:{
server(aSocket);
break;
}
default:{
close(aSocket);// закрываем сокет в родителе
}
}
}while(forkResult>0);