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

на главную

Жанры

UNIX: разработка сетевых приложений
Шрифт:
Преобразование сокета в прослушиваемый сокет

16
С помощью вызова функции
listen
сокет преобразуется в прослушиваемый, то есть такой, на котором ядро принимает входящие соединения от клиентов. Эти три этапа,
socket
,
bind
и
listen
, обычны для любого сервера TCP при создании того, что мы называем прослушиваемым дескриптором( listening descriptor) (в нашем примере это переменная
listenfd
).

Константа

LISTENQ
взята из нашего заголовочного файла
unp.h
. Она задает максимальное количество клиентских соединений, которые ядро ставит
в очередь на прослушиваемом сокете. Более подробно мы расскажем о таких очередях в разделе 4.5.

Прием клиентского соединения, отправка ответа

17-21
Обычно процесс сервера блокируется при вызове функции
accept
, ожидая принятия подключения клиента. Для установки TCP-соединения используется трехэтапное рукопожатие( three-way handshake). Когда рукопожатие состоялось, функция accept возвращает значение, и это значение является новым дескриптором (
connfd
), который называется присоединенным дескриптором( connected descriptor). Этот новый дескриптор используется для связи с новым клиентом. Новый дескриптор возвращается функцией
accept
для каждого клиента, соединяющегося с нашим сервером.

ПРИМЕЧАНИЕ

Стиль, используемый в книге для обозначения бесконечного цикла, выглядит так:

for (;;) {

...

}

Библиотечная функция

time
возвращает количество секунд с начала эпохи Unix: 00:00:00 1 января 1970 года UTC (Universal Time Coordinated — универсальное синхронизированное время, среднее время по Гринвичу). Следующая библиотечная функция,
ctime
, преобразует целочисленное значение секунд в строку следующего формата, удобного для человеческого восприятия:

Fri Jan 12 14:27:52 1996

Возврат каретки и пустая строка добавляются к строке функцией

snprintf
, а результат передается клиенту функцией
write
.

ПРИМЕЧАНИЕ

Если вы еще не выработали у себя привычку пользоваться функцией snprintf вместо устаревшей sprintf, сейчас самое время заняться этим. Функция sprintf не в состоянии обеспечить проверку переполнения буфера получателя. Функция snprintf, наоборот, требует, чтобы в качестве второго аргумента указывался размер буфера получателя, переполнение которого таким образом предотвращается.

Функция snprintf была добавлена в стандарт ANSI С относительно нравно, в версии ISO C99. Практически все поставщики программного обеспечения уже сейчас включают эту функцию в стандартную библиотеку языка С. Существуют и свободно распространяемые реализации. В нашей книге мы используем функцию snprintf и рекомендуем вам пользоваться ею в своих программах для повышения их надежности.

Удивительно много сетевых атак было реализовано хакерами с использованием незащищенности sprintf от переполнения буфера. Есть еще несколько функций, с которыми нужно быть аккуратными: gets, strcat и strcpy. Вместо них лучше использовать fgets, strncat и strncpy. Еще лучше работают более современные функции strlcat и strlcpy, возвращающие в качестве результата правильно завершенную строку. Полезные советы, касающиеся написания надежных сетевых программ, можно найти в главе 23 книги [32].

Завершение соединения

22
Сервер закрывает соединение с клиентом, вызывая функцию
close
. Это инициирует обычную последовательность прерывания соединения TCP: пакет FIN посылается в обоих направлениях, и каждый пакет FIN распознается на другом конце соединения. Более подробно трехэтапное рукопожатие и четыре пакета TCP, используемые для прерывания соединения, будут описаны в разделе 2.6.

Сервер времени и даты был рассмотрен нами достаточно кратко, как и клиент из предыдущего раздела. Запомните следующие моменты.

Сервер, как и клиент, зависим от протокола IPv4. В листинге 11.7 мы покажем версию, не зависящую от протокола, которая использует функцию

getaddrinfo
.

Наш сервер обрабатывает только один запрос клиента за один раз. Если приблизительно в одно время происходит множество клиентских соединений, ядро ставит их в очередь, максимальная длина которой регламентирована, и передает эти соединения функции accept по одному за один раз. Наш сервер времени и даты, который требует вызова двух библиотечных функций, time и ctime, является достаточно быстрым. Но если у сервера обслуживание каждого клиента занимает больше времени (допустим, несколько секунд или минуту), нам будет необходимо некоторым образом организовать одновременное обслуживание нескольких клиентов.

Сервер, показанный в листинге 1.5, называется последовательным сервером( iterative server), поскольку он обслуживает клиентов последовательно, по одному клиенту за один раз. Существует несколько технологий написания параллельного сервера( concurrent server), который обслуживает множество клиентов одновременно. Самой простой технологией является вызов функции Unix

fork
(раздел 4.7), когда создается по одному дочернему процессу для каждого клиента. Другой способ — использование программных потоков (threads) вместо функции
fork
(раздел 26.4) или предварительное порождение фиксированного количества дочерних процессов с помощью функции fork в начале работы (раздел 30.6).

Запуская такой сервер из командной строки, мы обычно рассчитываем, что он будет работать достаточно долго, поскольку часто серверы работают, пока работает система. Поэтому мы должны модифицировать код сервера таким образом, чтобы он корректно работал как демон( daemon) Unix, то есть процесс, функционирующий в фоновом режиме без подключения к терминалу. Это решение подробно описано в разделе 13.4.

1.6. Таблица соответствия примеров технологии клиент-сервер

Технологии сетевого программирования иллюстрируются в этой книге на двух основных примерах:

клиент-сервер времени и даты (описание которого мы начали в листингах 1.1, 1.2 и 1.5), и

эхо-клиент-сервер (который появится в главе 5).

Чтобы обеспечить удобный поиск различных тем, которых мы касаемся в этой книге, мы объединили разработанные нами программы и сопроводили их номерами листингов, в которых приведен исходный код. В табл. 1.1 перечислены версии клиента времени и даты (две из них мы уже видели). В табл. 1.2 перечисляются версии сервера времени и даты. В табл. 1.3 представлены версии эхо-клиента, а в табл. 1.4 — версии эхо-сервера.

Таблица 1.1. Различные версии клиента времени и даты

Листинг Описание
1.1 TCP/Ipv4, зависимый от протокола
1.2 TCP/Ipv6, зависимый от протокола
11.2 TCP/Ipv4, зависимый от протокола, вызывает функции gethostbyname и getservbyname
11.5 TCP, независимый от протокола, вызывает функции getaddrinfo и tcp_connect
11.10 UDP, независимый от протокола, вызывает функции getaddrinfo и udp_connect
16.7 TCP, использует неблокирующую функцию connect
31.2 TCP/IPv4, зависимый от протокола
Д.1 TCP, зависимый от протокола, генерирует SIGPIPE
Д.2 TCP, зависимый от протокола, печатает размер буфера сокета и MSS
Д.5 TCP, зависимый от протокола, допускает использование имени узла (функция gethostbyname) или IP-адреса
Д.6 TCP, независимый от протокола, допускает использование имени узла (функция gethostbyname).
Поделиться:
Популярные книги

Идущий в тени. Книга 2

Амврелий Марк
2. Идущий в тени
Фантастика:
фэнтези
6.93
рейтинг книги
Идущий в тени. Книга 2

Сонный лекарь 4

Голд Джон
4. Не вывожу
Фантастика:
альтернативная история
аниме
5.00
рейтинг книги
Сонный лекарь 4

Возрождение Феникса. Том 1

Володин Григорий Григорьевич
1. Возрождение Феникса
Фантастика:
фэнтези
попаданцы
альтернативная история
6.79
рейтинг книги
Возрождение Феникса. Том 1

Не грози Дубровскому!

Панарин Антон
1. РОС: Не грози Дубровскому!
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Не грози Дубровскому!

Покоритель Звездных врат

Карелин Сергей Витальевич
1. Повелитель звездных врат
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Покоритель Звездных врат

Партиец

Семин Никита
2. Переломный век
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Партиец

Эффект Фостера

Аллен Селина
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Эффект Фостера

В теле пацана 4

Павлов Игорь Васильевич
4. Великое плато Вита
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
В теле пацана 4

Ваше Сиятельство 7

Моури Эрли
7. Ваше Сиятельство
Фантастика:
боевая фантастика
аниме
5.00
рейтинг книги
Ваше Сиятельство 7

Уязвимость

Рам Янка
Любовные романы:
современные любовные романы
7.44
рейтинг книги
Уязвимость

Мой любимый (не) медведь

Юнина Наталья
Любовные романы:
современные любовные романы
7.90
рейтинг книги
Мой любимый (не) медведь

Смертник из рода Валевских. Книга 1

Маханенко Василий Михайлович
1. Смертник из рода Валевских
Фантастика:
фэнтези
рпг
аниме
5.40
рейтинг книги
Смертник из рода Валевских. Книга 1

Бездомыш. Предземье

Рымин Андрей Олегович
3. К Вершине
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Бездомыш. Предземье

Пустоши

Сай Ярослав
1. Медорфенов
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Пустоши