Предисловие
Сегодня сети применяются буквально повсеместно. В офисе компьютеры объединены в локальные сети, подключенные к Internet. Дома персональные компьютеры соединяются с Internet пока еще только время от времени, но для подключения все чаще используются стационарные кабели и модемы DSL. Новые беспроводные технологии, такие как Bluetooth, должны еще больше расширить область охвата сетей и включить в нее все, начиная от сотовых телефонов и заканчивая бытовыми приборами.
Такие перспективы открывают огромные возможности для новаторства. Создаются новые классы приложений, позволяющих воспользоваться постоянными высокоскоростными соединениями. Интерактивные игры дают возможность игрокам с разных точек Земли состязаться на виртуальных игровых площадках и мгновенно передавать друзьям известия о своих победах с применением протоколов экстренной передачи сообщений. Новые одноранговые системы, такие как Napster и Gnutella, позволяют непосредственно обмениваться звуковыми файлами в формате MP3 и другим информационным наполнением. В проекте SETI@Home используется свободное время миллионов персональных компьютеров во всем мире для поиска признаков внеземной жизни в огромной массе космического шума.
Сети проникают во все области человеческой деятельности, и это способствует также развитию обычных приложений. Обладая нужными знаниями, можно создать робот, который будет собирать и подытоживать данные с Web-узлов конкурентов; написать сценарий, автоматически сообщающий о падении курса определенных акций ниже указанного уровня; разработать программу подготовки ежедневных управленческих отчетов и отправки их по электронной почте; а также спроектировать сервер, который способен при одних условиях сосредоточить выполнение задачи, требующей большого объема вычислений, на одном мощном компьютере, а при других - распределить ее по нескольким узлам компьютерного кластера.
Тем не менее без понимания того, как работают сетевые приложения, невозможно полностью воспользоваться всеми преимуществами сети, независимо от того, решается ли задача поиска товаров по самой выгодной цене или поиска братьев по разуму в отдаленной галактике. Для этого, прежде всего, нужно уметь работать с протоколом TCP/IP, который не только лежит в основе всего взаимодействия по Internet, но и чаще всего применяется в локальной сети. Необходимо знать, как подключиться к удаленной программе, получить и передать в нее данные и как устранить возможные нарушения. Для работы с существующими приложениями, такими как Web-серверы, нужно знать, как реализованы прикладные протоколы, в основе которых лежит протокол TCP/IP, и как работать с широко применяемыми форматами обмена данных типа XML и MIME.
В настоящей книге рассматривается разработка и реализация практически применимых сетевых приложений с использованием языка программирования Perl. Этот язык идеально подходит для сетевого программирования по многим причинам. Во-первых, как и другие средства этого языка, сетевые модули Perl позволяют быстро решать поставленные задачи. На этом языке достаточно написать две строки кода, чтобы открыть сетевое соединение с сервером, находящимся где-то в Internet, и отправить ему сообщение. Полностью работоспособный Web-сервер может быть реализован с помощью нескольких десятков строк программы.
Во-вторых, Perl разрабатывается в рамках проекта с открытым исходным кодом, и это побудило многих талантливых программистов внести свой вклад в постоянно растущую библиотеку модулей независимых разработчиков. Многие из этих модулей предоставляют мощные интерфейсы к обычным сетевым приложениям. Например, после загрузки модуля LWP::Simple достаточно вызвать единственную функцию для выборки с удаленного сервера всего содержимого Web-страницы и сохранения его в переменной. Другие модули независимых разработчиков предоставляют простые интерфейсы к приложениям электронной почты, FTP, сетевых новостей, а также к различным сетевым базам данных.
Perl обладает также впечатляющей переносимостью. Большинство приложений, представленных в этой книге, могут работать без каких-либо изменений на платформах UNIX, Windows, Macintosh, VMS и OS/2.
Однако самым убедительным аргументов в пользу применения языка Perl для разработки сетевых приложений является то, что он позволяет полностью воспользоваться всеми возможностями TCP/IP. Perl предоставляет полный доступ к тем же сетевым вызовам низкого уровня, которые доступны в программах C и других транслируемых языках. Он позволяет создавать приложения многоадресной рассылки, развертывать мультиплексные серверы и разрабатывать одноранговые системы. Этот язык дает возможность быстро создавать прототипы новых сетевых приложений и разрабатывать интерфейсы к существующим. А когда настанет время подготовить сетевое приложение на языке C или Java, программист Perl с восхищением обнаружит, какая значительная часть API-интерфейса Perl пересекается с этими языками.
Для кого предназначена эта книга
Книга Разработка сетевых программ на Perl рассчитана на программистов Perl начального и среднего уровня. Автор предполагает, что читатель владеет основами программирования Perl, в частности, знает, как писать циклы, строить операторы if-else и создавать шаблоны регулярных выражений, а также имеет представление об автоматической переменной $_ и знает основы работы с массивами и хешами.
Для успешного изучения этой книги необходимо иметь доступ к интерпретатору Perl и обладать определенным опытом написания, выполнения и отладки сценариев. Не менее важно также иметь доступ к компьютеру, подключенному и к локальной сети, и к Internet! Хотя для выполнения рекомендаций по автоматическому запуску сетевых серверов на основе Perl во время начальной загрузки компьютера, приведенных в главе 10, требуется доступ на уровне суперпользователя (администратора), все другие примеры этой книги могут быть выполнены без привилегированного доступа к компьютеру.
В данной книге используются объектно-ориентированные средства Perl версии 5 и последующих версий, но материал большинства глав не требует глубоких знаний в области объектно-ориентированного программирования. В главе 1 приведены все сведения, необходимые для первого знакомства с объектами Perl.
Здесь не представлен полный обзор протокола TCP/IP, вплоть до самого низкого уровня. Данная книга не может служить руководством по установке и настройке сетевых концентраторов, маршрутизаторов и серверов имен. Литература с описанием протокола TCP/IP и изложением вопросов сетевого администрирования приведена в Приложении Г, "Библиография".
Краткий обзор содержания книги
Эта книга состоит из четырех основных частей.
В части I, Основы, представлены основные сведения о сетевых средствах связи протокола TCP/IP.
- В главах 1 и 2, "Основы ввода-вывода" и "Процессы, каналы и сигналы", описаны функции и переменные, применяемые для ввода и вывода, рассмотрены исключительные ситуации, которые могут возникать во время выполнения операций ввода-вывода, и дано вводное описание сокетов на примере дескрипторов файлов, применяемых для ввода-вывода по каналу. В этих главах приведен также обзор модели обработки Perl, включая сигналы и средства ветвления (порождения дочерних процессов), и представлены объектно-ориентированные расширения Perl.
- В главе 3, "Основные сведения о сокетах Berkeley", приведены основные сведения о сетевых средствах Internet, дано описание IP-адресов и сетевых портов, а также рассмотрены принципы создания приложений типа клиент/сервер. В конце главы приведено описание API-интерфейса сокетов Berkeley - программного интерфейса к TCP/IP.
- Главы 4 и 5, "Протокол TCP" и "API-интерфейс IO::Socket", содержат описание основ TCP - сетевого протокола, который обеспечивает надежное потоковое взаимодействие процессов. В этих главах показано, как создавать клиентские и серверные приложения, и представлены примеры, которые демонстрируют возможности этих методов, а также могут служить образцами для создания наиболее часто применяемых приложений.
В части II, Разработка клиентов для основных служб, рассматривается коллекция лучших модулей независимых разработчиков, которые были внесены в Полный сетевой архив Perl (CPAN).
- В главе 6, "FTP и Telnet", описаны модули, которые обеспечивают применение службы совместного доступа к файлам по протоколу FTP, а также представлен гибкий и удобный модуль Net::Telnet, который позволяет создавать клиенты для работы с различными сетевыми службами.
- Электронная почта все еще занимает доминирующее положение в Internet, и в главе 7, "Протокол отправки почты SMTP", описано, как выполнить первую задачу организации обмена почтовыми сообщениями - отправку почты. В этой главе показано, как динамически создавать сообщения электронной почты, в том числе двоичные файловые дополнения, и отправлять их по месту назначения.
- В главе 8, "Протоколы обработки почты и сообщений групп новостей POP, IMAP и NNTP", рассматривается вторая задача - получение почты. В этой главе описаны модули, позволяющие принимать электронную почту от удаленных почтовых систем и обрабатывать полученные письма, которые могут содержать двоичные файловые дополнения.
- Глава 9, "Web-клиенты", содержит описание модуля LWP, предоставляющего все необходимое для подключения к Web-серверу, загрузки и обработки документов HTML, а также интерпретации документов XML.
В части III, Разработка систем TCP типа клиент/сервер (самой большой по объему), описаны возможности проектирования систем типа клиент/сервер на основе протокола TCP. В качестве основного примера в этих главах применяется психотерапевтический интерактивный сервер, созданный по образцу классической программы Eliza Джозефа Вейценбаума (Joseph Weizenbaum).
- В главе 10, "Серверы с ветвлением и демон inetd", описан TCP-сервер обычного типа, который порождает собственную копию для обработки каждого входящего соединения. В этой главе рассматриваются также демоны inetd UNIX и Windows, позволяющие использовать в качестве сетевых серверов программы, которые не были специально предназначены для этой цели.
- Глава 11, "Многопоточные приложения", содержит описание экспериментального многопоточного API-интерфейса Perl. В этой главе показано, что применение такого интерфейса позволяет значительно упростить проектирование клиентов и серверов TCP.
- В главах 12 и 13, "Мультиплексные приложения" и "Неблокирующий ввод-вывод", рассматривается функция select(), которая позволяет обрабатывать в приложении несколько потоков ввода-вывода одновременно без мультипроцессной или многопоточной обработки.
- В главе 14, "Повышение безотказности серверов", обсуждаются методы повышения надежности и безотказности сетевых серверов. В этой главе рассматриваются такие темы, как ведение журналов, обработка сигналов и исключений, а также важная тема защиты сети.
- В главе 15, "Предварительная организация мультипроцессной и многопоточной обработки", представлены более развитые модели ветвления и формирования потоков команд по сравнению с описанными в предыдущих главах. Эти усовершенствования позволяют повысить способность сервера выдерживать тяжелые нагрузки.
- Глава 16, "Модуль IO::Poll", содержит описание одного варианта, который может применяться на платформах UNIX вместо функции select(). Этот модуль позволяет мультиплексировать в приложении несколько потоков ввода-вывода с использованием API-интерфейса, который многие находят более удобным по сравнению с интерфейсом функции select().
В части IV, Дополнительные темы, рассматриваются методы, которые предназначены для специализированных приложений.
- Глава 17, "Срочные данные TCP", посвящена срочным или "внеочередным" данным TCP. Этот метод передачи данных часто применяется в интерактивных приложениях для отправки сигналов управления на удаленный сервер.
- В главах 18 и 19, "Протокол UDP" и "Серверы UDP", представлен протокол пользовательских дейтаграмм, который позволяет легко создать службу связи, ориентированную на передачу сообщений. В главе 18 описан сам протокол, а в главе 19 показано, как разрабатывать серверы UDP. Основным примером, рассматриваемым в этой и следующих двух главах, служит система прямого чата (оперативного обмена текстовыми сообщениями) и передачи сообщений, написанная полностью на языке Perl.
- Главы 20 и 21, "Широковещательная рассылка" и "Многоадресная рассылка", содержат описание новых областей применения протокола UDP. В этих главах показано, как построить систему передачи сообщений типа "от одного ко всем" и "от одного ко многим". Здесь рассматривается более развитая система чата, которая включает средства автоматического обнаружения сервера и многоадресной рассылки.
- В главе 22, "Сокеты домена UNIX", показано, как создавать каналы связи между процессами на одном и том же компьютере, действующие на основе упрощенного протокола. Эти средства могут применяться в таких специализированных приложениях, как программа ведения журнала.
Многочисленные версии Perl
Любой перспективный проект проходит определенные этапы своего развития, и язык Perl, который пересматривался несколько раз на протяжении своего недолгого существования, не составляет исключения. В настоящей книге рассматривается Perl версии 5.X (рекомендуется версия 5.003 или последующая). Ко времени написания этого предисловия (август 2000 года) самой новой версией Perl была 5.6 и готовилась к выпуску версия 5.7. Автор предполагает, что язык Perl версий 5.8 и 5.9 (если они появятся) также будет совместимым с приведенными здесь примерами кода.
Однако ведется работа по созданию Perl версии 6. В этой версии, которая должна выйти в виде первой альфа-версии в 2001 году, будут исправлены многие "странности" и недостатки ранних версий Perl. Но это может привести к нарушению работы большинства существующих сценариев. К счастью, разработчики языка Perl взяли на себя обязательства разработать инструментальные средства, позволяющие автоматически перенести существующие сценарии на версию 6. Учитывая это, автор попытался сделать примеры в этой книге универсальными и не применять в них наиболее сложные конструкции Perl.
Совместимость с разными платформами
Более серьезной проблемой являются различия между реализациями Perl в разных операционных системах. Perl начал свое развитие в системах UNIX (и Linux), а затем был перенесен на многие другие операционные системы, включая Microsoft Windows, Macintosh, VMS, OS/2, Plan9 и т.д. Сценарии, написанные на платформе Windows, могут работать в системе UNIX или Macintosh без изменений.
Однако проблема состоит в том, что подсистема ввода-вывода (та часть операционной системы, которая управляет операциями ввода и вывода) обнаруживает наиболее существенные отличия на разных операционных системах. Это ограничивает возможность добиться полной переносимости системы ввода-вывода Perl. Хотя основные функциональные средства ввода-вывода Perl на разных платформах одинаковы, некоторые более сложные операции на платформах, отличных от UNIX, либо отсутствуют, либо имеют существенные отличия. Это, безусловно, влияет и на сетевое программирование, поскольку в основе работы сети лежит ввод и вывод данных.
В примерах глав 1-9 применяются универсальные сетевые функции, которые работают одинаково на всех платформах. Исключением является последний пример в главе 5, в котором предусмотрен вызов функции fork(), не реализованной на платформе Macintosh, и часть вводного описания в главе 2, которое касается управления процессами в системе UNIX. Методы, описанные в этих главах, содержат все необходимое для написания подавляющего большинства клиентских программ и являются достаточными для создания и применения простого сервера. В главах 10-22 рассматриваются более сложные вопросы проектирования сервера. Ниже приведена таблица, которая позволяет узнать, какие средства, рассматриваемые в этих главах, поддерживаются в версиях Perl для UNIX, Windows или Macintosh.
(Условные обозначения: "+" - поддерживаемые средства; "-" - не поддерживаемые средства; "P" - частичная поддержка.)
Обнадеживающим фактором является также то, что версии Perl для платформ, отличных от UNIX, быстро развиваются, и вполне возможно, что к тому времени, когда эта книга попадет в руки читателя, появятся многие новые средства.
Все примеры сценариев и модулей, приведенные в этой книге, можно получить на Web-узле в форматах ZIP и TAR/GZIP по адресу: http://www.modperl.com/perl_networking. На этой странице даны также инструкции по распаковке и установке исходного кода.
Многие сетевые модули Perl уже включены в стандартный дистрибутив, а другие являются модулями независимых разработчиков, которые необходимо загрузить из Web и установить. Большинство модулей независимых разработчиков написано только на языке Perl, но некоторые из них, включая и упомянутые в этой книге, частично написаны на языке C и должны быть оттранслированы перед использованием.
CPAN - это размещенная в Web большая коллекция модулей Perl, предоставленных в общее пользование. Доступ к этой коллекции может быть получен с помощью Web-броузера, клиента FTP или приложения с интерфейсом командной строки, встроенного в сам интерпретатор Perl.
Чтобы найти ближайший узел CPAN, введите в Web-броузере адрес: http://www.cpan.org/. Откроется страница, на которой можно выполнить поиск конкретных модулей или просмотреть весь список модулей, предоставленных в общее пользование, который может быть отсортирован разными способами. Отыскав нужный вам модуль, загрузите его на локальный компьютер.
Модули Perl распространяются в виде архивов tar, сжатых программой gzip. Их можно распаковать следующим образом.
После распаковки архива перейдите во вновь созданный каталог и введите команду perl Makefile.PL, make, make test и make install. В результате будет выполнена сборка, проверка и установка модуля.
В системах UNIX для выполнения последнего этапа могут потребоваться права суперпользователя. Не имея таких прав, вы можете установить модули только в своем рабочем каталоге. На этапе выполнения команды perl Makefile.PL укажите в параметре PREFIX= путь к своему рабочему каталогу. Например, если путь к рабочему каталогу - /home/jdoe, необходимо ввести следующее.
Остальная часть процедуры установки аналогична описанной выше.
При использовании каталога установки, определяемого пользователем, необходимо указать интерпретатору Perl, в каком каталоге должен выполняться поиск установленных модулей. Одним из способов этого является включение имени этого каталога в переменную среды PERL5LIB.
Еще один способ состоит в размещении следующей строки в начале каждого сценария, в котором применяется установленный модуль.
Более простым способом выполнения установки модуля является использование замечательной командной оболочки CPAN Андреаса Кенига (Andreas Koenig). Она позволяет найти, загрузить, собрать и установить необходимый модуль Perl с помощью простой командной оболочки. Все эти действия выполняет команда install.
Во всех этих примерах предполагается наличие на компьютере версий программ gzip, tar и make, совместимых с UNIX. В стандартных системах Windows эти утилиты отсутствуют. Пакет Cygwin, который может быть получен по адресу: http://www.cygnus.com/cygwin/, предоставляет указанные утилиты в составе полного набора инструментальных средств, совместимых с UNIX.
Однако проще применить диспетчер пакетов Perl (PPM - Perl Package Manager), разработанный компанией ActiveState. Эта программа представляет собой сценарий Perl, устанавливаемый по умолчанию в составе дистрибутива Perl компании ActiveState, который может быть получен по адресу: http://www.activestate.com. Интерфейс этой программы аналогичен интерфейсу командной строки оболочки CPAN, показанному в предыдущем разделе, за исключением того, что он позволяет устанавливать не только сценарии на языке Perl, но и заранее оттранслированные программы и библиотеки.
Узел MacPerl Module Porters, находящийся по адресу: http://pudge.net/cgi-bin/mmp.plx, содержит ряд модулей, предназначенных для использования в дистрибутиве MacPerl. Разработан также ряд вспомогательных программ, позволяющих упростить установку модулей в системе Macintosh. Эти пакеты описаны на странице http://pudge.net/macperl/macperlmodinstall.html, где также даны инструкции по их загрузке и установке.
В настоящей книге приведены ссылки не только на книги и Web-узлы, но и на два других важных источника оперативной информации: документы RFC Internet и документацию POD Perl.
Документы, которые по традиции носят название RFC (Requests for Comment - Запросы на комментарии), выпущены Проблемной группой проектирования Internet (IETF - Internet Engineering Task Force). Здесь даны спецификации всех основных протоколов Internet. Эти документы пронумерованы последовательно. Например, RFC 1927, Suggested Additional MIME Types for Associating Documents. (Предлагаемые дополнительные типы MIME для обозначения документов), был 1927-м документом RFC, выпущенным этой комиссией. Некоторые из этих документов в конечном итоге становятся стандартами Internet, и в этом случае им присваивают имя STD и последовательный номер. Однако большинство из них так и остается "предложениями к обсуждению". Но даже несмотря на то, что такие документы RFC не утверждены официально, они могут применяться для изучения деталей устройства сетевых протоколов и проверки правильности конкретной реализации.
Копии архивов RFC хранятся на многих зеркальных узлах в Internet и ведутся несколькими организациями в форме, обеспечивающей удобный поиск. Один из наилучших архивов ведется на узле http://www.faqs.org/rfcs/. Для получения RFC с этого узла перейдите на указанную страницу и введите номер требуемого RFC в текстовом поле Display the document by number. Документ будет доставлен в форме с минимальным применением разметки HTML. На этой странице можно также выполнять поиск стандартов, а также искать документы в архиве по ключевым словам и фразам. Если вы предпочитаете чисто текстовую форму, то на узле www.faqs.org есть ссылка на FTP-узел, где можно найти и загрузить документы в их первоначальной форме RFC.
Значительная часть внутренней документации Perl представлена в формате POD (Plain Old Documentation - "Добрая старая" документация). Этот формат в основном представляет собой обычный текст, в который вставлено несколько элементов разметки для обозначения заголовков, подзаголовков и структурированных списков.
Во время установки Perl выполняется также установка документации POD. Файлы POD находятся в подкаталоге pod библиотечного каталога Perl.
Эти документы можно читать непосредственно либо необходимо использовать сценарий perldoc для их форматирования и отображения в текстовом виде в программе постраничного просмотра, такой как more.
Для использования perldoc введите эту команду и имя нужного файла POD. Обычно лучше всего начать с оглавления Perl, perltoc.
В результате появится список страниц POD, которые можно вывести на экран. Для получения краткой справки по конкретной функции Perl можно вызвать сценарий perldoc с флажком -f. Например, чтобы получить справку по функции socket(), введите следующее.
В дистрибутив MacPerl для компьютера Macintosh входит вспомогательное приложение shuck. Оно предоставляет средства просмотра POD с помощью справочного меню MacPerl.
Говорят, что работа редактора, прежде всего, учит терпению, но мне кажется, что Карэн Геттмен (Karen Gettman) родилась с этим качеством. Она действительно могла бы потерять выдержку, когда я в очередной раз заявлял: "Обязательно закончу книгу через пару недель", и это тянулось месяцами. Однако она никогда не показывала своего недовольства, хотя я уверен, что ей приходилось выдерживать все более жесткое давление со стороны производственного и маркетингового персонала издательства. Карэн, я не нахожу слов, чтобы выразить свою признательность!
Хочу также поблагодарить Мэри Харт (Mary Hart), помощника редактора, которая отвечала за подготовку моей книги. Я работал с Мэри над другими проектами и знаю, что только неустанные усилия таких сотрудников, как она, обеспечивают бесперебойную и эффективную работу издательства Addison-Wesley.
Весьма признателен техническим рецензентам, которые так внимательно следили за тем, чтобы я не допустил ни одной ошибки: Йону Орванту (Jon Orwant), Джеймсу Ли (James Lee), Гарри Хоххейзеру (Harry Hochheiser), Роберту Колстеду (Robert Kolstad), Сандеру Валсу (Sander Wahls) и Меган Конклин (Megan Conklin). Книга стала гораздо лучше благодаря вашим усилиям.
Выражаю свою благодарность терпеливым сотрудникам моей лаборатории - Рави, Дэвиду, Марко, Хонгу, Гуанмин, Натали и Питеру; они как-то ухитрялись продолжать начатое дело даже в течение последних месяцев подготовки рукописи, когда мои утренние опоздания становились все более продолжительными.
И конечно, хочу сказать спасибо моей жене, Джин, которая уже пережила вместе со мной выпуск нескольких проектов и знает, что я не каждый день могу с ней посидеть за одним обеденным столом.