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

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

Уважаемые читатели!
Тут можно читать бесплатно UNIX: разработка сетевых приложений - Уильям Стивенс. Жанр: Программное обеспечение. Так же Вы можете читать полную версию (весь текст) онлайн книги без регистрации и SMS на сайте Knigi-online.info (книги онлайн) или прочесть краткое содержание, описание, предисловие (аннотацию) от автора и ознакомиться с отзывами (комментариями) о произведении.
Описание онлайн-книги UNIX: разработка сетевых приложений - Уильям Стивенс:
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.

Аудиокнига "UNIX: разработка сетевых приложений" от Уильяма Стивенса



📚 "UNIX: разработка сетевых приложений" - это увлекательное путешествие в мир UNIX и сетевого программирования. В книге автор подробно рассматривает основные принципы разработки сетевых приложений под UNIX, раскрывая множество интересных тем и примеров.



Главный герой книги - опытный разработчик, который стремится углубить свои знания в области сетевого программирования под UNIX. Он исследует различные аспекты работы с сетью, изучает протоколы передачи данных и на практике применяет полученные знания.



👨‍💻 Уильям Стивенс - известный специалист в области компьютерных наук, автор множества книг по сетевому программированию. Его работы пользуются популярностью среди разработчиков и студентов по всему миру.



На сайте knigi-online.info вы можете бесплатно и без регистрации слушать аудиокниги онлайн на русском языке. Здесь собраны бестселлеры и лучшие произведения различных жанров, чтобы каждый мог найти что-то по душе.



🎧 Погрузитесь в увлекательный мир UNIX и сетевого программирования вместе с аудиокнигой "UNIX: разработка сетевых приложений" от Уильяма Стивенса. Развивайте свои навыки, открывайте новые горизонты и наслаждайтесь процессом обучения!

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

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 127 128 129 130 131 132 133 134 135 ... 263

 9   err_quit("usage: tcpcli <IPaddress>");

10  sockfd = Socket(AF_INET, SOCK_STREAM, 0);

11  bzero(&servaddr, sizeof(servaddr));

12  servaddr.sin_family = AF_INET;

13  servaddr.sin_port = htons(SERV_PORT);

14  Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);

15  Connect(sockfd, (SA*)&servaddr, sizeof(servaddr));

16  ling.l_onoff = 1; /* для отправки сегмента RST при закрытии соединения */

17  ling.l_linger = 0;

18  Setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling));

19  Close(sockfd);

20  exit(0);

21 }

Установка параметра сокета SO_LINGER

16-19 Как только соединение устанавливается, мы задаем параметр сокета SO_LINGER, устанавливая флаг l_onoff в единицу и обнуляя время l_linger. Как утверждалось в разделе 7.5, это вызывает отправку RST на сокете TCP при закрытии соединения. Затем с помощью функции close мы закрываем сокет.

Потом мы изменяем наш сервер TCP, приведенный в листингах 6.3 и 6.4, с тем чтобы после сообщения функции select о готовности прослушиваемого сокета для чтения, но перед вызовом функции accept наступала пауза. В следующем коде, взятом из начала листинга 6.4, две добавленные строки помечены знаком +.

  if (FD_ISSET(listenfd, &rset)) { /* новое соединение */

+  printf("listening socket readablen");

+  sleep(5);

   clilen = sizeof(cliaddr);

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

Здесь мы имитируем занятый сервер, который не может вызвать функцию accept сразу же, как только функция select сообщит, что прослушиваемый сокет готов для чтения. Обычно подобное замедление со стороны сервера не вызывает проблем (на самом деле именно для этих ситуаций предусмотрена очередь полностью установленных соединений). Но поскольку после установления соединения от клиента прибыл сегмент RST, у нас возникает проблема.

В разделе 5.11 мы отмечали, что когда клиент разрывает соединение до того, как сервер вызывает функцию accept, в Беркли-реализациях прерванное соединение не возвращается серверу, в то время как другие реализации должны возвращать ошибку ECONNABORTED, но часто вместо нее возвращают ошибку EPROTO. Рассмотрим Беркли-реализацию.

■ Клиент устанавливает соединение и затем прерывает его, как показано в листинге 16.14.

■ Функция select сообщает процессу сервера, что дескриптор готов для чтения, но у сервера вызов функции accept занимает некоторое, хотя и непродолжительное, время.

■ После того, как сервер получил сообщение от функции select, и прежде, чем была вызвана функция accept, прибыл сегмент RST от клиента.

■ Установленное соединение удаляется из очереди, и мы предполагаем, что не существует никаких других установленных соединений.

■ Сервер вызывает функцию accept, но поскольку установленных соединений нет, он оказывается заблокирован.

Сервер останется блокированным в вызове функции accept до тех пор, пока какой-нибудь другой клиент не установит с ним соединение. Но если сервер аналогичен показанному в листинге 6.4, в это время он заблокирован в вызове функции accept и не может обрабатывать никакие другие готовые дескрипторы.

ПРИМЕЧАНИЕ

Проблема в некоторой степени аналогична проблеме, называемой атакой типа «отказ в обслуживании», описанной в разделе 6.8. Однако в данном случае сервер выходит из состояния блокировки, как только другой клиент установит соединение.

Чтобы решить эту проблему, нужно соблюдать два следующих правила:

1. Всегда делать прослушиваемый сокет неблокируемым, если мы используем функцию select для определения того, готово ли соединение к обработке функцией accept.

2. Игнорировать следующие ошибки, возникающие при повторном вызове функции accept: EWOULDBLOCK (для Беркли-реализаций, когда клиент разрывает соединение), ECONNABORTED (для реализаций POSIX, когда клиент разрывает соединение), EPROTO (для реализаций SVR4, когда клиент разрывает соединение) и EINTR (если перехватываются сигналы).

16.7. Резюме

В примере неблокируемого чтения и записи в разделе 16.2 использовался наш клиент str_cli, который мы изменили для применения неблокируемого ввода-вывода на соединении TCP с сервером. Функция select обычно используется с неблокируемым вводом-выводом для определения того момента, когда дескриптор станет готов для чтения или записи. Эта версия нашего клиента является самой быстродействующей из всех показанных версией, хотя требует нетривиального изменения кода. Затем мы показали, что проще разделить процесс клиента на две части при помощи функции fork. Мы используем ту же технологию при создании потоков в листинге 26.1.

Неблокируемая функция connect позволяет нам во время трехэтапного рукопожатия TCP выполнять другие задачи вместо блокирования в вызове функции connect. К сожалению, с этими функциями также связана проблема совместимости, так как различные реализации по-разному указывают, успешно ли установлено соединение или произошла ошибка. Мы использовали неблокируемые соединения для создания нового клиента, аналогичного веб-клиенту, открывающему одновременно множество соединений TCP для уменьшения затрат времени при получении нескольких файлов от сервера. Подобное инициирование множества соединений может сократить временные затраты, но также является «недружественным по отношению к сети», поскольку не позволяет воспользоваться алгоритмом TCP, предназначенным для предотвращения перегрузки (congestion avoidance).

Упражнения

1. Обсуждая листинг 16.6, мы отметили, что родительский процесс должен вызвать функцию shutdown, а не функцию close. Почему?

2. Что произойдет в листинге 16.6, если процесс сервера завершится преждевременно и дочерний процесс получит признак конца файла, но не уведомит об этом родительский процесс?

3. Что произойдет в листинге 16.6, если родительский процесс непредвиденно завершится до завершения дочернего процесса, и дочерний процесс затем считает конец файла на сокете?

4. Что произойдет в листинге 16.7, если мы удалим следующие две строки:

if (n == 0)

 goto done; /* функция connect завершилась немедленно */

5. В разделе 16.3 мы сказали, что возможна ситуация, когда данные для сокета придут раньше, чем завершится функция connect. Когда это может случиться?

Глава 17

Операции функции ioctl

17.1. Введение

Функция ioctl традиционно являлась системным интерфейсом, используемым для всего, что не входило в какую-либо другую четко определенную категорию. POSIX постепенно избавляется от функции ioctl, создавая заменяющие ее функции-обертки и стандартизуя их функциональность. Например, доступ к интерфейсу терминала Unix традиционно осуществлялся с помощью функции ioctl, но в POSIX были созданы 12 новых функций для терминалов: tcgetattr для получения атрибутов терминала, tcflush для опустошения буферов ввода или вывода, и т.д. Аналогичным образом POSIX заменяет одну сетевую функцию ioctl: новая функция sockatmark (см. раздел 24.3) заменяет команду SIOCATMARK ioctl. Тем не менее прочие сетевые команды ioctl остаются не стандартизованными и могут использоваться, например, для получения информации об интерфейсе и обращения к таблице маршрутизации и кэшу ARP (Address Resolution Protocol — протокол разрешения адресов).

В этой главе представлен обзор команд функции ioctl, имеющих отношение к сетевому программированию, многие из которых зависят от реализации. Кроме того, некоторые реализации, включая системы, происходящие от 4.4BSD и Solaris 2.6, используют сокеты домена AF_ROUTE (маршрутизирующие сокеты) для выполнения многих из этих операций. Маршрутизирующие сокеты мы рассматриваем в главе 18.

Обычно сетевые программы (как правило, серверы) используют функцию ioctl для получения информации обо всех интерфейсах узла при запуске программы, с тем чтобы узнать адрес интерфейса, выяснить, поддерживает ли интерфейс широковещательную передачу, многоадресную передачу и т.д. Для возвращения этой информации мы разработали нашу собственную функцию. В этой главе мы представляем ее реализацию с применением функции ioctl, а в главе 18 — другую реализацию, использующую маршрутизирующие сокеты.

17.2. Функция ioctl

Эта функция работает с открытым файлом, дескриптор которого передается через аргумент fd.

#include <unistd.h>

int ioctl(int fd, int request, ... /* void *arg */ );

Возвращает: 0 в случае успешного выполнения, -1 в случае ошибки

Третий аргумент всегда является указателем, но тип указателя зависит от аргумента request.

1 ... 127 128 129 130 131 132 133 134 135 ... 263
На этой странице вы можете бесплатно читать книгу UNIX: разработка сетевых приложений - Уильям Стивенс бесплатно.
Похожие на UNIX: разработка сетевых приложений - Уильям Стивенс книги

Оставить комментарий

Рейтинговые книги