Программирование для 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
(коммутируемое соединение). Поделиться:
Популярные книги
Цеховик. Книга 2. Движение к цели
2. Цеховик
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Сильнейший Столп Империи. Книга 4
4. Сильнейший Столп Империи
Фантастика:
фэнтези
аниме
фантастика: прочее
попаданцы
5.00
рейтинг книги
Неверный
Любовные романы:
современные любовные романы
5.50
рейтинг книги
#НенавистьЛюбовь
Любовные романы:
современные любовные романы
6.33
рейтинг книги
Родословная. Том 2
2. Линия крови
Фантастика:
городское фэнтези
аниме
фэнтези
5.00
рейтинг книги
На границе империй. Том 7. Часть 5
11. Фортуна дама переменчивая
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
Курсант: назад в СССР
1. Курсант
Фантастика:
попаданцы
альтернативная история
7.33
рейтинг книги
Полонянин
2. Ночь Сварога
Приключения:
исторические приключения
8.30
рейтинг книги
Последний Паладин
1. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Жена со скидкой, или Случайный брак
Любовные романы:
любовно-фантастические романы
8.15
рейтинг книги
Лейб-хирург
2. Зауряд-врач
Фантастика:
альтернативная история
7.34
рейтинг книги
Принадлежать им
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Хроники Тириса. Книга 1
1. Хроники Тириса
Фантастика:
боевая фантастика
космическая фантастика
фантастика: прочее
6.00
рейтинг книги
Стеллар. Заклинатель
3. Стеллар
Фантастика:
боевая фантастика
8.40