Продолжая использовать наш сайт, вы даете согласие на обработку файлов cookie, которые обеспечивают правильную работу сайта. Благодаря им мы улучшаем сайт!
Принять и закрыть

Читать, слущать книги онлайн бесплатно!

Электронная Литература.

Бесплатная онлайн библиотека.

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


Помоги проекту - поделись книгой:

У. Р. Стивенс, Б. Феннер, Э. М. Рудофф

UNIX

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

3-е издание

Рику

Aloha nui loa

Вступительное слово

Вышедшее в 1990 году первое издание этой книги было признано лучшим учебником для программистов, изучающих технологии сетевого программирования. С тех пор сеть претерпела серьезнейшие изменения. Достаточно взглянуть на адрес автора, указанный в том издании: «uunet!hsi!netbook». Вряд ли любой читатель сможет сказать, что это адрес в сети UUCP, которая была популярна в 1980-х.

Сейчас сети UUCP стали раритетом, а новые технологии, подобные беспроводным сетям, получают повсеместное распространение. Разрабатываются новые протоколы и парадигмы программирования. И программисты начинают ощущать потребность в учебнике, который помог бы им освоить все тонкости новых методик.

Книга, которую вы держите в руках, заполняет этот пробел. Тем, у кого на книжной полке стоит истрепанное первое издание, она даст возможность узнать о новых технологиях программирования и о протоколах следующего поколения, таких как IPv6. Эта книга нужна всем, потому что она представляет собой соединение практического опыта, исторической перспективы и глубины понимания.

Я уже получил удовольствие и новые знания благодаря этой книге, и не сомневаюсь, что вы сможете сделать то же самое.

Сэм Леффлер

Предисловие

Введение

Эта книга предназначена для тех, кто хочет писать программы, взаимодействующие друг с другом посредством интерфейса сокетов. Некоторые читатели, возможно, уже достаточно хорошо знакомы с сокетами, потому что сейчас сетевое программирование фактически немыслимо без них. Другим придется начинать с самых азов. Цель этой книги — предоставить руководство по сетевому программированию для начинающих и для профессионалов, тех, кто разрабатывает новые сетевые приложения и тех, кто поддерживает существующий код. Будет полезна она и тем, кто хочет понимать, как работают сетевые компоненты их систем.

Все примеры в этой книге относятся к операционной системе Unix, хотя основные понятия и концепции сетевого программирования практически не зависят от операционной системы. Почти все операционные системы предоставляют набор сетевых приложений, таких как браузеры, почтовые клиенты и файловые серверы. Мы обсудим обычное деление таких приложений на клиентскую и серверную части и напишем множество примеров собственных клиентов и серверов.

Ориентируясь на Unix, мы не могли не рассказать о самой этой системе и о TCP/IP. В тех случаях, когда читателю могут оказаться интересными более подробные сведения, мы отсылаем его к другим книгам:

■ Advanced Programming in the Unix Environment [110];

■ TCP/IP Illustrated, том 1 [111];

■ TCP/IP Illustrated, том 2 [128];

■ TCP/IP Illustrated, том 3 [112].

В первую очередь читателю следует обращаться к книге [128], в которой представлена реализация 4.4BSD функций сетевого программирования для API сокетов (socket, bind, connect и т.д.). При понимании того, как реализована та или иная функциональная возможность, ее применение в приложениях становится более осмысленным.

Изменения по сравнению со вторым изданием

Сокеты в нынешней их форме существовали с 1980-х годов. Благодаря совершенству архитектуры этого интерфейса, он продолжает оставаться оптимальным для большинства приложений. Возможно, вы будете удивлены, узнав, как много изменилось в этом интерфейсе с 1998 года, когда было опубликовано второе издание этой книги. Эти изменения были отражены в новом издании. Их можно сгруппировать следующим образом:

■ Новое издание содержит обновленные сведения об IPv6, который на момент публикации второго издания существовал только в черновом варианте, и за прошедшие годы был усовершенствован.

■ Определения функций и примеры их использования были изменены в соответствии с последней спецификацией POSIX (POSIX 1003.1–2001), которая известна под названием «Единая спецификация UNIX версии 3».

■ Описание транспортного интерфейса X/Open было исключено из книги, потому что этот интерфейс вышел из широкого употребления и последняя спецификация POSIX не описывает его.

■ Также исключено было описание протокола TCP для транзакций (T/TCP).

■ Были добавлены три новые главы, посвященные относительно новому транспортному протоколу SCRIPT. Этот надежный протокол, ориентированный на передачу сообщений, предоставляет поддержку многопоточной передачи и обеспечивает работу с несколькими интерфейсами. Изначально он был предназначен для Интернет-телефонии, но его функции могут оказаться полезными многим другим приложениям.

■ Также была добавлена глава, посвященная сокетам управления ключами, которые могут использоваться с протоколом IPSec и другими сервисами сетевой безопасности.

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

 □ Apple Power PC с MacOS/X 10.2.6

 □ HP PA-RISC с HP-UX 11i

 □ IBM Power PC с AIX 5.1

 □ Intel x86 с FreeBSD 4.8

 □ Intel x86 с Linux 2.4.7

 □ Sun SPARC с FreeBSD 5.1

 □ Sun SPARC с Solaris 9

Второй том под названием «Взаимодействие процессов» рассказывает о передаче сообщений, синхронизации, разделяемой памяти и удаленном вызове процедур.

Кому адресована эта книга

Эту книгу можно использовать и как учебное пособие по сетевому программированию, и как справочник для более опытных программистов. При использовании его как учебника или для ознакомления с сетевым программированием следует уделить особое внимание второй части («Элементарные сокеты», главы 3–11), после чего можно переходить к чтению тех глав, которые представляют наибольший интерес. Во второй части рассказывается об основных функциях сокетов как для TCP, так и для UDP; кроме того, рассматривается мультиплексирование ввода-вывода, параметры сокетов и основные преобразования имен и адресов. Всем читателям следует прочесть главу 1, в особенности раздел 1.4, так как в нем описаны некоторые функции-обертки, используемые далее во всей книге. Глава 2 и, возможно, приложение А могут быть использованы по мере необходимости для получения справочных сведений в зависимости от уровня подготовки читателя. Большинство глав в третьей части («Дополнительные возможности сокетов») могут быть прочитаны независимо от других, содержащихся в этой же части.

Для тех, кто собирается использовать эту книгу в качестве справочного пособия, имеется подробный предметный указатель. Для тех, кто будет читать только выборочные главы в произвольном порядке, в книге имеются ссылки на те места, где обсуждаются близкие темы.

Исходный код и замеченные опечатки

Исходный код для всех примеров расположен на моей домашней странице[1], адрес которой указан в конце предисловия. Чтобы научиться сетевому программированию, лучше всего будет взять эти программы, изменить их и расширить. На самом деле написание программ таким образом является единственным способом овладеть изученными технологиями. В конце каждой главы приводятся упражнения, а ответы на большинство из них содержатся в приложении Г.

Список найденных опечаток по этой книге также находится на моей домашней странице.

Благодарности

Первое и второе издания этой книги были написаны У. Ричардом Стивенсом, который скончался 1 сентября 1999 г. Его книги стали образцом учебной литературы по сетевому программированию и считаются яркими, тщательно проработанными и необычайно популярными произведениями искусства. Авторы новой редакции постарались сохранить качество книги на прежнем уровне.

Без поддержки семьи и друзей написать книгу невозможно. Билл Феннер хотел бы поблагодарить свою жену Пегги (чемпионку в беге на четверть мили) и соседа по дому Кристофера Бойда за то, что они взяли на себя все тяготы домашнего труда на время его работы над этим проектом. Нужно поблагодарить и Джерри Виннера, чья поддержка была незаменима. Энди Рудофф благодарен своей жене Эллен и дочерям Джо и Кэти за понимание и поощрение. Без вашей помощи мы бы не справились с этим.

Рэндолл Стюарт из Cisco Systems предоставил большую часть материала по SCRIPT и заслуживает отдельной благодарности за свой бесценный вклад. Без помощи Рэндолла мы не смогли бы рассказать ничего на эту новую интересную тему.

Многочисленные рецензенты помогли ценными замечаниями и указаниями, обращая внимание на многочисленные ошибки и те области, которые требовали более подробного изложения, а также предложили альтернативные варианты формулировок, изложения материала и самих программ. Авторы хотели бы поблагодарить Джеймса Карлсона, Ву-Чана Фена, Рика Джонса, Брайана Кернигана, Сэма Леффлера, Джона МакКанна, Крейга Метца, Яна Ланса Тейлора, Дэвида Шварца и Гари Райта.

Многие люди и те организации, в которых они работали, шли мне навстречу, предоставляя программное обеспечение или доступ к системе, необходимые для тестирования некоторых примеров к книге.

■ Джесси Хог из IBM Austin предоставила систему AIX и компиляторы.

■ Рик Джонс и Уильям Гиллэм из Hewlett-Packard предоставили доступ ко множеству систем под управлением HP-UX.

Истинным удовольствием было работать с персоналом Addison Wesley: Норин Региной, Кэтлин Кэрен, Дэном де Паскуале, Энтони Гемелларо и Мэри Франц, нашим редактором, которая заслуживает отдельных благодарностей.

Продолжая традиции Рика Стивенса (но в противоположность общепринятым технологиям), мы подготовили оригинал-макет книги, используя замечательный пакет groff, написанный Джеймсом Кларком (James Clark), создали иллюстрации с помощью программы gpic (используя многие из макросов Гари Райта), сделали таблицы с помощью программы gtbl, составили предметный указатель и подготовили окончательный макет страниц. Программа Дейва Хансона (Dave Hanson) loom и некоторые сценарии Гари Райта (Gary Wright) использовались для включения кода программ в книгу. Набор сценариев на языке awk, написанный Джоном Бентли (Jon Bentley) и Брайаном Керниганом (Brian Kernighan), помогал в создании предметного указателя.

Авторы с нетерпением ждут комментарии, предложения и сообщения о замеченных опечатках.

authors@unpbook.com

http://www.unpbook.com

От издательства

Ваши замечания, предложения, вопросы отправляйте по адресу электронной почты comp@piter.com (издательство «Питер», компьютерная редакция).

Мы будем рады узнать ваше мнение!

Исходные коды всех программ, приведенных в книге, вы можете найти по адресу http://www.piter.com.

На веб-сайте издательства http://www.piter.com вы найдете подробную информацию о наших книгах.

Часть 1

Введение. TCP/IP

Глава 1

Введение в сетевое программирование

1.1. Введение

Чтобы писать программы, рассчитанные на взаимодействие в компьютерных сетях, необходимо сначала изобрести протокол — соглашение о порядке взаимодействия таких программ. Прежде чем углубляться в детальное проектирование протокола, нужно принять некоторые высокоуровневые решения о том, какая программа будет инициировать передачу данных и в каких случаях можно ожидать ответной передачи. Например, веб-сервер обычно рассматривается как долгоживущая программа (или демонdaemon), которая отправляет сообщения исключительно в ответ на запросы, поступающие по сети. Другой стороной является веб-клиент, например браузер, который всегда начинает взаимодействие с сервером первым. Деление на клиенты и серверы характерно для большинства сетевых приложений. И протокол, и программы обычно упрощаются, если возможность отправки запросов предоставляется только клиенту. Конечно, некоторые сетевые приложения более сложной структуры требуют поддержки асинхронного обратного вызова (asynchronous callback), то есть инициации передачи сообщений сервером, а не клиентом. Однако гораздо чаще приложения реализуются в базовой модели клиент-сервер, изображенной на рис. 1.1.


Рис. 1.1. Сетевое приложение: клиент и сервер

Клиенты обычно устанавливают соединение с одним сервером за один раз, хотя, если в качестве примера говорить о веб-браузере, мы можем соединиться со множеством различных веб-серверов, скажем, в течение 10 минут. Сервер, напротив, в любой момент времени может быть соединен со множеством клиентов. Это отражено на рис. 1.2. Далее в этой главе будут рассмотрены различные возможности взаимодействия сервера одновременно со множеством клиентов.


Рис. 1.2. Сервер, который одновременно обслуживает множество клиентов

Не будет большой ошибкой сказать, что клиентское и серверное приложения взаимодействуют по сетевому протоколу, однако фактически в большинстве случаев используется несколько протоколов различных уровней. В этой книге мы сосредоточимся на наборе (стеке) протоколов TCP/IP, также называемом набором протоколов Интернета. Так, например, клиенты и веб-серверы устанавливают соединения, используя протокол управления передачей (Transmission Control Protocol, TCP). TCP, в свою очередь, использует протокол Интернета (Internet Protocol, IP), а протокол IP устанавливает соединение с тем или иным протоколом канального уровня. Если и клиент, и сервер находятся в одной сети Ethernet, взаимодействие между ними будет осуществляться по схеме, изображенной на рис. 1.3.


Рис. 1.3. Клиент и сервер в одной сети Ethernet, соединенные по протоколу TCP

Хотя клиент и сервер устанавливают соединение с использованием протокола уровня приложений, транспортные уровни устанавливают соединение, используя TCP. Обратите внимание, что действительный поток информации между клиентом и сервером идет вниз по стеку протоколов на стороне клиента, затем по сети и, наконец, вверх по стеку протоколов на стороне сервера.

Заметьте, что клиент и сервер являются типичными пользовательскими процессами, в то время как TCP и протоколы IP обычно являются частью стека протоколов внутри ядра. Четыре уровня протоколов обозначены на рис. 1.3 справа.

Мы будем обсуждать не только протоколы TCP и IP. Некоторые клиенты и серверы используют протокол пользовательских дейтаграмм (User Datagram Protocol, UDP) вместо TCP; оба эти протокола более подробно обсуждаются в главе 2. Мы часто пользуемся термином «IP», но на самом деле протокол, который мы при этом подразумеваем, называется «IP версии 4» (IP version 4, IPv4). Новая версия этого протокола, IP версии 6 (IPv6), была разработана в середине 90-х и, возможно, со временем заменит протокол IPv4. В этой книге описана разработка сетевых приложений как под IPv4, так и под IPv6. В приложении А приводится сравнение протоколов IPv4 и IPv6 наряду с другими протоколами, с которыми мы встретимся.

Клиент и сервер не обязательно должны быть присоединены к одной и той же локальной сети (local area network, LAN), как в примере на рис. 1.3. Вместо этого, как показано на рис. 1.4, клиент и сервер могут относиться к разным локальным сетям, при этом обе локальных сети должны быть соединены в глобальную сеть (wide area network, WAN) с использованием маршрутизаторов.


Рис. 1.4. Клиент и сервер в различных локальных сетях, соединенных через глобальную сеть

Маршрутизаторы — это «кирпичи», из которых строится глобальная сеть. На сегодня наибольшей глобальной сетью является Интернет, хотя многие компании создают свои собственные глобальные сети, и эти частные сети могут быть, а могут и не быть подключены к Интернету.

Оставшаяся часть этой главы представляет собой введение и обзор различных тем, которые более подробно раскрываются далее по тексту книги. Мы начнем с полного, хотя и простого, примера клиента TCP, на котором демонстрируются вызовы многих функций и понятия, с которыми мы встретимся далее. Клиент работает только с протоколом IPv4, и мы покажем изменения, необходимые для работы с протоколом IPv6. Разумнее всего создавать независимые от протокола клиенты и серверы, и такое решение будет рассмотрено нами в главе 11. Мы приводим также код полнофункционального сервера TCP, работающего с нашим клиентом.

Чтобы упростить написанный нами код, мы определяем наши собственные функции-обертки (wrapper functions) для большинства вызываемых системных функций. Функции-обертки в большинстве случаев служат для проверки кода возврата. В случае ошибки функция-обертка печатает соответствующее сообщение и завершает работу программы.

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

В разговорах о Unix широко используется термин «X», обозначающий стандарт, принятый большинством производителей. Мы опишем историю стандарта POSIX и то, каким образом он определяет интерфейсы программирования приложений (Application Programming Interfaces, API), рассматриваемые в этой книге, наряду с другими конкурирующими стандартами.

1.2. Простой клиент времени и даты

Рассмотрим конкретный пример, на котором мы введем многие понятия и термины, используемые в этой книге. В листинге 1.1[1] представлена реализация TCP-клиента времени и даты. Этот клиент устанавливает TCP-соединение с сервером, а сервер просто посылает клиенту время и дату в текстовом формате.

Листинг 1.1. Клиент TCP для определения времени и даты

//intro/daytimetcpcli.с

 1 #include "unp.h"

 2 int

 3 main(int argc, char **argv)

 4 {

 5  int sockfd, n;

 6  char recvline[MAXLINE + 1];

 7  struct sockaddr_in servaddr;

 8  if (argc != 2)

 9   err_quit("usage: a.out <Ipaddress>");

10  if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)

11   err_sys("socket error");



Поделиться книгой:

На главную
Назад