/* Бесконечный цикл обработки запросов. */ while (1){ struct sockaddr_in remote_address; socklen_t address_length; int connection; pid_t child_pid; /* Прием запроса. Эта функция блокируется до тех пор, пока не поступит запрос. */ address_length = sizeof (remote_address); connection = accept(server_socket, &remote_address, &address_length); if (connection == -1){ /* Функция завершилась неудачно. */ if (errno==EINTR) /* Функция была прервана сигналом. Повторная попытка. */ continue; else /* Что-то случилось. */ system_error("accept"); } /* Соединение установленно. Вывод сообщения, если сервер работает в режиме развёрнутых сообщений. */ if (verbose) { socklen_t address_length; /* Получение адресса клиента. */ address_length = sizeof(socket_address); rval = getpeername (connection, &socket_address, &address_length); assert (rval == 0); /* Вывод сообщения. */ printf("connection accepted from %s\n", inet_ntoa (socket_address.sin_addr)); } /* Создание дочерниго процесса для обработки запроса. */ child_pid = fork(); if (child_pid == 0){ /* Это дочерний процесс. Потоки stdin и stdout ему не нужны, поэтому закрываем их. */ close(STDIN_FILENO); close(STDOUT_FILENO); /* Дочерний процесс не должен работать с серверным сокетом, поэтому закрываем его дескриптор. */ close(server_socket); /* Обработка запроса. */ handle_connection(connection); /* Обработка завершена. Закрываем соединение и завершаем дочерний процесс. */ close(connection); exit(0); } else if (child_pid > 0){ /* Это родительский процесс. Дескриптор клиентского сокета ему не нужен. Переход к приёму следующего запроса. */ close(connection); } else /* Выхов fork() завершился неудачей. */ system_error("fork"); }