Чтение онлайн

на главную - закладки

Жанры

Программирование для 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
(коммутируемое соединение).

Поделиться:
Популярные книги

Моя на одну ночь

Тоцка Тала
Любовные романы:
современные любовные романы
короткие любовные романы
5.50
рейтинг книги
Моя на одну ночь

Черный Маг Императора 8

Герда Александр
8. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 8

Измена. Отбор для предателя

Лаврова Алиса
1. Отбор для предателя
Фантастика:
фэнтези
5.00
рейтинг книги
Измена. Отбор для предателя

Кодекс Крови. Книга II

Борзых М.
2. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга II

Шаг в бездну

Муравьёв Константин Николаевич
3. Перешагнуть пропасть
Фантастика:
фэнтези
космическая фантастика
7.89
рейтинг книги
Шаг в бездну

Часовая битва

Щерба Наталья Васильевна
6. Часодеи
Детские:
детская фантастика
9.38
рейтинг книги
Часовая битва

Вечная Война. Книга II

Винокуров Юрий
2. Вечная война.
Фантастика:
юмористическая фантастика
космическая фантастика
8.37
рейтинг книги
Вечная Война. Книга II

Хроники странного королевства. Вторжение. (Дилогия)

Панкеева Оксана Петровна
110. В одном томе
Фантастика:
фэнтези
9.38
рейтинг книги
Хроники странного королевства. Вторжение. (Дилогия)

Часовой ключ

Щерба Наталья Васильевна
1. Часодеи
Фантастика:
фэнтези
9.36
рейтинг книги
Часовой ключ

Инвестиго, из медика в маги

Рэд Илья
1. Инвестиго
Фантастика:
фэнтези
городское фэнтези
попаданцы
5.00
рейтинг книги
Инвестиго, из медика в маги

Кротовский, может, хватит?

Парсиев Дмитрий
3. РОС: Изнанка Империи
Фантастика:
попаданцы
альтернативная история
аниме
7.50
рейтинг книги
Кротовский, может, хватит?

Драконий подарок

Суббота Светлана
1. Королевская академия Драко
Любовные романы:
любовно-фантастические романы
7.30
рейтинг книги
Драконий подарок

Очешуеть! Я - жена дракона?!

Амеличева Елена
Фантастика:
юмористическая фантастика
5.43
рейтинг книги
Очешуеть! Я - жена дракона?!

Идеальный мир для Лекаря 9

Сапфир Олег
9. Лекарь
Фантастика:
боевая фантастика
юмористическое фэнтези
6.00
рейтинг книги
Идеальный мир для Лекаря 9