Стивенс Уильям Ричард
Шрифт:
Мы написали клиентскую и серверную части программы и продемонстрировали их использование вообще без явного сетевого программирования. Клиент просто вызывает две функции, а сервер вообще состоит из одной функции. Все тонкости использования XTI в Solaris, сокетов в BSD/OS и сетевого ввода-вывода обрабатываются библиотекой RPC времени выполнения. В этом и состоит предназначение RPC — предоставлять возможность создания распределенных приложений без знания сетевого программирования.
Другая немаловажная деталь данного примера заключается в том, что в системах Sparc под Solaris и Intel x86 под управлением BSD/OS используется разный порядок байтов. В Sparc используется порядок big endian («тупоконечный» [2] ), а в Intel — little endian («остроконечный») (что мы показали в разделе 3.4 [24]). Отличия в порядке байтов также обрабатываются библиотекой RPC времени выполнения автоматически с использованием стандарта XDR (внешнее представление данных), который мы обсудим в разделе 16.8.
2
Проблема о порядке байтов в слове сродни проблеме лилипутов из «Путешествий Гулливера» Д. Свифта, которые никак не могли договориться, с какого конца начинать есть яйцо. Именно оттуда англоязычные программисты взяли термины little-endian (остроконечник) и big-endian (тупоконечник), подразумевая «little-end-first» и «big-end-first» (младший или старший байт идет первым). — Примеч. перев.
Создание программы-клиента и программы-сервера в данном случае требует больше операций, чем для любой другой программы этой книги. Выполняемый файл клиента получается следующим образом:
Параметр –С говорит rpcgen о необходимости создания прототипов функций ANSI С в заголовочном файле square.h. Программа rpcgen также создает заглушку клиента (client stub) в файле с именем square_clnt.с и файл с именем square_xdr.с, который осуществляет преобразование данных в соответствии со стандартом XDR. Наша библиотека (содержащая функции, используемые в этой книге) называется libunpipc.a, а параметр –lnsl подключает системную библиотеку сетевых функций в Solaris (включая библиотеки RPC и XDR времени выполнения).
Аналогичные команды используются для создания сервера, хотя rpcgen уже не нужно запускать снова. Файл square_svc.c содержит функцию main сервера, и файл square_xdr.о, обсуждавшийся выше, также требуется для работы сервера:
При этом создаются клиент и сервер, выполняемые в системе Solaris.
Если клиент и сервер должны быть построены для разных систем (как в предыдущем примере, где клиент выполнялся в Solaris, а сервер — в BSD/OS), могут потребоваться дополнительные действия. Например, некоторые файлы должны быть либо общими (через NFS), либо находиться в обеих системах, а файлы, используемые клиентом и сервером (например, square_xdr.o), должны компилироваться в каждой системе в отдельности.
Рис. 16.1. Этапы создания приложения клиент-сервер с использованием RPC
На рис. 16.1 приведена схема создания приложения типа клиент-сервер. Три затемненных прямоугольника соответствуют файлам, которые мы должны написать. Штриховые линии показывают файлы, подключаемые через заголовочный файл square.h.
На рис. 16.2 изображена схема происходящего при удаленном вызове процедуры. Действия выполняются в следующем порядке:
1. Запускается сервер, который регистрируется в программе, управляющей портами на узле-сервере. Затем запускается клиент и вызывает clnt_create. Эта функция связывается с управляющей портами программой сервера и находит нужный порт. Функция clnt_create также устанавливает соединение с сервером по протоколу TCP (поскольку мы указали TCP в качестве используемого протокола в листинге 16.2). Мы не показываем эти шаги на рисунке и откладываем детальное обсуждение до раздела 16.3.
2. Клиент вызывает локальную процедуру, называемую заглушкой клиента. В листинге 16.2 эта процедура называлась squareproc_1, а файл, содержащий ее, создавался rpcgen автоматически и получал название square_clnt.c. С точки зрения клиента именно эта функция является сервером, к которому он обращается. Целью создания заглушки является упаковка аргументов для удаленного вызова процедуры, помещение их в стандартный формат и создание одного или нескольких сетевых сообщений. Упаковка аргументов клиента в сетевое сообщение называется сортировкой (marshaling). Клиент и заглушка обычно вызывают библиотеки функций RPC (clnt_create в нашем примере). При использовании редактора связей в Solaris эти функции загружаются из библиотеки –lnsl, тогда как в BSD/OS они входят в стандартную библиотеку языка С.