UNIX: разработка сетевых приложений

На нашем литературном портале можно бесплатно читать книгу UNIX: разработка сетевых приложений, Стивенс Уильям Ричард-- . Жанр: ОС и Сети. Онлайн библиотека дает возможность прочитать весь текст и даже без регистрации и СМС подтверждения на нашем литературном портале bazaknig.info.
UNIX: разработка сетевых приложений
Название: UNIX: разработка сетевых приложений
Дата добавления: 16 январь 2020
Количество просмотров: 771
Читать онлайн

UNIX: разработка сетевых приложений читать книгу онлайн

UNIX: разработка сетевых приложений - читать бесплатно онлайн , автор Стивенс Уильям Ричард

Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.

Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала

Перейти на страницу:

38     continue; /* назад в for() */

39    else

40     err_sys("select error");

41   }

42   if (FD_ISSET(listenfd, &rset)) {

43    len = sizeof(cliaddr);

44    connfd = Accept(listenfd, (SA*)&cliaddr, &len);

45    if ((childpid = Fork()) == 0) { /* дочерний процесс */

46     Close(listenfd); /* закрывается прослушиваемый сокет */

47     str_echo(connfd); /* обработка запроса */

48     exit(0);

49    }

50    Close(connfd); /* родитель закрывает присоединенный сокет */

51   }

52   if (FD_ISSET(udpfd, &rset)) {

53    len = sizeof(cliaddr);

54    n = Recvfrom(udpfd, mesg, MAXLINE, 0, (SA*)&cliaddr, &len);

55    Sendto(udpfd, mesg, n, 0, (SA*)&cliaddr, len);

56   }

57  }

58 }

Установка обработчика сигнала SIGCHLD

30
 Для сигнала
SIGCHLD
устанавливается обработчик, поскольку соединения TCP будут обрабатываться дочерним процессом. Этот обработчик сигнала мы показали в листинге 5.8.

Подготовка к вызову функции select

31-32
 Мы инициализируем набор дескрипторов для функции
select
и вычисляем максимальный из двух дескрипторов, готовности которого будем ожидать.

Вызов функции select

34-41
 Мы вызываем функцию
select
, ожидая только готовности к чтению прослушиваемого сокета TCP или сокета UDP. Поскольку наш обработчик сигнала
sig_chld
может прервать вызов функции
select
, обрабатываем ошибку
EINTR
.

Обработка нового клиентского соединения

42-51
 С помощью функции
accept
мы принимаем новое клиентское соединение, а когда прослушиваемый сокет TCP готов для чтения, с помощью функции
fork
порождаем дочерний процесс и вызываем нашу функцию
str_echo
в дочернем процессе. Это та же последовательность действий, которую мы выполняли в главе 5.

Обработка приходящей дейтаграммы

52-57
 Если сокет UDP готов для чтения, дейтаграмма пришла. Мы читаем ее с помощью функции
recvfrom
и отправляем обратно клиенту с помощью функции
sendto
.

8.16. Резюме

Преобразовать наши эхо-клиент и эхо-сервер так, чтобы использовать UDP вместо TCP, оказалось несложно. Но при этом мы лишились множества возможностей, предоставляемых протоколом TCP: определение потерянных пакетов и повторная передача, проверка, приходят ли пакеты от корректного собеседника, и т.д. Мы возвратимся к этой теме в разделе 22.5 и увидим, как можно улучшить надежность приложения UDP.

Сокеты UDP могут генерировать асинхронные ошибки, то есть ошибки, о которых сообщается спустя некоторое время после того, как пакет был отправлен. Сокеты TCP всегда сообщают приложению о них, но в случае UDP для получения этих ошибок сокет должен быть присоединенным.

В UDP отсутствует возможность управления потоком, что очень легко продемонстрировать. Обычно это не создает проблем, поскольку многие приложения UDP построены с использованием модели «запрос-ответ» и не предназначены для передачи большого количества данных.

Есть еще ряд моментов, которые нужно учитывать при написании приложений UDP, но мы рассмотрим их в главе 22 после описания функций интерфейсов, широковещательной и многоадресной передачи.

Упражнения

1. Допустим, у нас имеется два приложения, одно использует TCP, а другое — UDP. В приемном буфере сокета TCP находится 4096 байт данных, а в приемном буфере для сокета UDP — две дейтаграммы по 2048 байт. Приложение TCP вызывает функцию

read
с третьим аргументом 4096, а приложение UDP вызывает функцию
recvfrom
с третьим аргументом 4096. Есть ли между этими вызовами какая-нибудь разница?

2. Что произойдет в листинге 8.2, если мы заменим последний аргумент функции

sendto
(который мы обозначили
len
) аргументом
clilen
?

3. Откомпилируйте и запустите сервер UDP из листингов 8.1 и 8.4, а затем — клиент из листингов 8.3 и 8.4. Убедитесь в том, что клиент и сервер работают вместе.

4. Запустите программу

ping
в одном окне, задав параметр
-i 60
(отправка одного пакета каждые 60 секунд; некоторые системы используют ключ
I
вместо
i
), параметр
-v
(вывод всех полученных сообщений об ошибках ICMP) и задав адрес закольцовки на себя (обычно 127.0.0.1). Мы будем использовать эту программу, чтобы увидеть ошибку ICMP недоступности порта, возвращаемую узлом сервера. Затем запустите наш клиент из предыдущего упражнения в другом окне, задав IP-адрес некоторого узла, на котором не запущен сервер. Что происходит?

5. Рассматривая рис. 8.3, мы сказали, что каждый присоединенный сокет TCP имеет свой собственный буфер приема. Как вы думаете, есть ли у прослушиваемого сокета свой собственный буфер приема?

6. Используйте программу

sock
(см. раздел В.3) и такое средство, как, например,
tcpdump
(см. раздел В.5), чтобы проверить утверждение из раздела 8.10: если клиент с помощью функции
bind
связывает IP-адрес со своим сокетом, но отправляет дейтаграмму, исходящую от другого интерфейса, то результирующая дейтаграмма содержит IP-адрес, который был связан с сокетом, даже если он не соответствует исходящему интерфейсу.

7. Откомпилируйте программы из раздела 8.13 и запустите клиент и сервер на различных узлах. Помещайте

printf
в клиент каждый раз, когда дейтаграмма записывается в сокет. Изменяет ли это процент полученных пакетов? Почему? Вызывайте
printf
из сервера каждый раз, когда дейтаграмма читается из сокета. Изменяет ли это процент полученных пакетов? Почему?

8. Какова наибольшая длина, которую мы можем передать функции

sendto
для сокета UDP/IPv4, то есть каково наибольшее количество данных, которые могут поместиться в дейтаграмму UDP/IPv4? Что изменяется в случае UDP/IPv6?

Перейти на страницу:
Комментариев (0)
название