Программирование для 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
(коммутируемое соединение). Поделиться:
Популярные книги
Кодекс Охотника. Книга XXXIX
39. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
боевая фантастика
5.00
рейтинг книги
Я до сих пор царь. Книга XXXII
32. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Барон ненавидит правила
8. Закон сильного
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Представь себе… Беседы о деньгах, политике и жизни вообще
Религия и эзотерика:
самосовершенствование
5.00
рейтинг книги
Точка Бифуркации VI
6. ТБ
Фантастика:
фэнтези
попаданцы
аниме
5.40
рейтинг книги
Свадьба на выбор, или Женихи в ассортименте
Любовные романы:
современные любовные романы
7.71
рейтинг книги
Неучтенный элемент. Том 10
10. Антимаг. Вне системы
Фантастика:
фэнтези
5.25
рейтинг книги
Литрпг
5.00
рейтинг книги
Тринадцатый
1. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
7.33
рейтинг книги
Записки уцелевшего
Документальная литература:
биографии и мемуары
7.00
рейтинг книги
Мифы и правда о плане Барбаросса
Анатомия армии
Научно-образовательная:
история
5.00
рейтинг книги
Цикл "Идеальный мир для Лекаря". Компиляция. Книги 1-30
Лекарь
Фантастика:
боевая фантастика
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Игра киллера
Детективы:
боевики
6.25
рейтинг книги
Законы рода
1. Граф Берестьев
Фантастика:
фэнтези
боевая фантастика
аниме
4.75