Программирование для Linux. Профессиональный подход
Шрифт:
для приема запросов. */
memset(&socket_address, 0, sizeof(socket_address));
socket_address.sin_family = AF_INET;
socket_address.sin_port = port;
socket_address.sin_addr = local_address;
/* Привязка сокета к этому адресу. */
rval =
bind(server_socket, &socket_address,
sizeof(socket_address));
if (rval != 0)
system_error("bind");
/* Перевод сокета в режим приема запросов. */
rval = listen(server_socket, 10);
if (rval != 0)
system_error("listen");
if (verbose) {
/* В режиме развернутых сообщений отображаем адрес и порт,
с которыми работает сервер. */
socklen_t address_length;
/* Нахождение адреса сокета. */
address_length = sizeof(socket_address);
rval =
getsockname(server_socket, &socket_address, &address_length);
assert(rval == 0);
/* Вывод сообщения. Номер порта должен быть преобразован
из сетевого (обратного) порядка следования байтов
в серверный (прямой). */
printf("server listening on %s:%d\n",
inet_ntoa(socket_address.sin_addr),
(int)ntohs(socket_address.sin_port));
}
/* Бесконечный цикл обработки запросов. */
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");
}
}
В файле
server.c
определены следующие функции. ■ Функция
server_run
является телом сервера. Она запускает сервер и начинает принимать запросы на подключение, не завершаясь до тех пор, пока не произойдет серьезная ошибка. Сервер создает потоковый TCP-сокет (см. раздел 5.5.3, "Серверы"). Первый аргумент функции
server_run
определяет локальный адрес, по которому принимаются запросы. У компьютера может быть несколько адресов, каждый из которых соответствует определённому сетевому интерфейсу. [37] Данный аргумент ограничивает работу сервера конкретным интерфейсом или разрешает принимать запросы отовсюду, если равен INADDR_ANY
.37
В системе могут присутствовать такие интерфейсы, как
eth0
(Ethernet-плата), lo
(интерфейс обратной связи), ppp0
(коммутируемое соединение). Поделиться:
Популярные книги
Хозяин Теней 7
7. Безбожник
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Гримуар темного лорда II
2. Гримуар темного лорда
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Герой. Том 1
1. Последний герой
Фантастика:
попаданцы
альтернативная история
фантастика: прочее
5.00
рейтинг книги
Белые погоны
3. Гибрид
Фантастика:
фэнтези
попаданцы
технофэнтези
аниме
5.00
рейтинг книги
Гримуар темного лорда IX
9. Гримуар темного лорда
Фантастика:
попаданцы
альтернативная история
аниме
фэнтези
5.00
рейтинг книги
Кодекс Охотника. Книга XIII
13. Кодекс Охотника
Фантастика:
боевая фантастика
попаданцы
аниме
7.50
рейтинг книги
Железный Воин Империи II
2. Железный Воин Империи
Фантастика:
фэнтези
попаданцы
аниме
5.75
рейтинг книги
Бастард Императора. Том 11
11. Бастард Императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Вернувшийся: Первые шаги. Том II
2. Вернувшийся
Фантастика:
боевая фантастика
космическая фантастика
рпг
5.00
рейтинг книги
Прапорщик. Назад в СССР. Книга 6
6. Второй шанс
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Родословная. Том 4
4. Линия крови
Фантастика:
городское фэнтези
аниме
фэнтези
5.00
рейтинг книги
Офицер
1. Офицер
Фантастика:
боевая фантастика
7.21
рейтинг книги
Мастер решений
3. Специалист по выживанию
Фантастика:
боевая фантастика
космическая фантастика
6.20
рейтинг книги
Эволюционер из трущоб. Том 9
9. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00