Программирование >>  Структура ядра и системные вызовы 

1 ... 67 68 69 [ 70 ] 71 72 73 ... 98


perror( sysinfо ); return -1;

else strcpy(host,argv[3]); return 0;

int main( int argc, char* argv[l) (

char buf(801, host[80];

int port=-l, cltsl port=-l, rc, flags=0;

if (argc < 2) (

cerr usage: argv[0] <serviceIport no>

<cltsl serviceIno> [<host>]\n ;

return 1;

/* проверить, указан ли номер порта */ (void)sscanf(argv[l], %d . Sport); (void) sscanf (argv[2], %d ,scltsl port);

tli *sp;

if (port==-l) (

if (gethost(argc, argv, host, sizeof host) < 0) return 2;

sp = new tli( host, argv(l], 1 ); } else sp = new tli (port, 1);

if (!sp I I !sp->good()} (

cerr clts2: create transport endpoint object failsXn ; return 2;

/* присвоить имя конечной точке транспортировки */ If (sp->Bind() < 0) (

cerr clts2: bind failsXn ;

return 3;

if (port==-l)

rc = sp->writeto(MSG2,strlen(MSG2)+1, 0, argv[2], host); else rc = sp->writeto(MSG2, strlen(MSG2)+1, 0, cltsl port); if (rc < 0) (

cerr clts2: writeto failsXn ; return 4;

struct t unitdata *ud = 0;

if (sp->readfrom(buf, sizeof buf, flags, ud) < 0) (

cerr clts2: readfrom filsXn ; return 5;

cerr clts2: read msg: buf Xn ;

if (

(sp->writeto(MSG3, strlen(MSG3}+1, flags, ud) < 0)

cerr clts2: writeto failsXn ; return 6;

return 0;

Программа tli clts2 очень похожа на программу tli cltsl. Отличие состоит в том, что она может вызываться не в одном, а в двух вариантах: во-первых, с назначенным целочисленным адресом и целочисленным адресом процесса tli cltsl (для случая локального соединения); во-вторых, с именем своего сервиса и именем сервиса tli cltsl, за которым может следовать необязательное хост-имя машины (при установлении Internet-соединения). Если указывается имя сервиса, это имя должно быть занесено в файл /etc/services. Если хост-имя не указывается, берется хост-имя локальной машины.

Работа программы tli clts2 начинается с создания конечной точки TLI по заданным аргументам командной строки. Если необходимо создать конечную точку транспортировки для Internet, то вызывается функция gethost, которая выявляет хост-имя локальной маишны из аргумента командной строки (если он есть) или посредством вызова функции sysinfo.

После создания конечной точки TLI процесс присваивает ей имя, а затем посылает сообшение MSG2 в процесс tli cltsl. После передачи сообшения MSG2 процесс ждет, когда процесс tlijcltsl пошлет ему сообшение MSGI. По его получении процесс направляет сообшение на стандартный вывод.

Наконец, процесс посылает в процесс tlicltsl сообшение MSG1 и завершается. Конечная точка транспортировки, созданная процессом, уничтожается функцией-деструктором ТЫ::~ТЫ.

Приведенный ниже протокол отражает взаимодействие процессов tli cltsl и tli clts2. Создаваемые в ходе взаимодействия конечные точки транспортировки имеют адреса, значения которых являются целыми числами. Конечной точке транспортировки процесса tlijcltsl присваивается адрес 1, а процесса tli clts2 - адрес 2: , ,. -, . л .,

* СС -о tli % СС -о tli % tli cltsl bind: 1

% tli clts2 bind: 2 cltsl: read msg: clts2: read msg: cltsl: read msg: [1] + Done tli

cltsl clts2 l &

t-ll dltl№iWlhel tli clts2.Crslunsi-

Hello MSG2 Hello MSGl Hello MSG3 cltsl 1

from clts2 from cltsl from clts2



Чтобы эту программу можно было выполнять с использованием хост-имен и имен сервисов, в файле /etc/services необходимо создать следующие записи:

utstl 4046/udp utst2 4047/udp

Здесь utstl - это имя сервиса, используемого процессом tlijdtsl, а utst2 - имя сервиса, используемое процессом tli clts2. Оба сервиса используют провайдер транспорта UDP, который предусматривает проведение сеанса связи без установления соединения.

Следующий протокол отражает взаимодействие этих же процессов, осуществляемое с использованием конечных точек транспортировки и сети Internet:

% tli cltsl utstl & bind: 135123 % tli clts2 utst2 utstl bind: 135124

cltsl: read msg: Hello MSG2 from clts2 clts2: read msg: Hello MSGl from cltsl cltsl: read msg: Hello MSG3 from clts2

[1] + Done

tli cltsl utstl

Обратите внимание: результат данного сеанса связи идентичен результату, полученному при работе с локальными конечными точками транспортировки. Перекомпилировать программы tli cltsl.Cwi tli clts2.Cне нужно. Эти же программы можно выполнять на разных мащинах, включенных в локальную сеть. Предположим, что программа tli cltsl выполняется на мащине с именем fruit, а программа tli clts2 - на мащине apple. Как вызываются эти программы, описано ниже.

Запускаем программу tlijcltsl на мащине fruit.

fruit % tli cltsl utstl &

[1425]

Запускаем программу tli clts2 на мащине apple:

apple % tli clts2 utst2 utstl fruit

После того как между компьютерами будет установлено соединение, выходные сообщения tlijcltsl будут выводиться на экран мащины fruit, а сообщения tli clts2 - на экран мащины apple.

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

В данной главе подробно описывается синтаксис интерфейсов прикладного программирования гнезд и ТЫ. Приводятся примеры программ, иллюстрирующие применение этих механизмов. Определяются класс sock и класс ТЫ, инкапсулирующие эти API и позволяющие пользователям, которые рещили применить такие конструкции для создания приложений IPC, сократить затраты времени на программирование.

Интерфейс транспортного уровня более гибок в применении, чем гнезда, потому что он поддерживает почти все транспортные протоколы. При организации взаимодействия с помощью гнезд может использоваться ограниченное число протоколов, причем гнезда разных типов поддерживают различные наборы протоколов. Кроме того, в ТЫ применяются более эффективные методы управления памятью (функции tjalloc и t Jree), информирования об ошибках в пересылке сообщений (t error, t rcvuderr, tjook) и осуществления разрыва соединений (tli snddis, tli rcvdis, tlijsndrel, tli rcvrel). Поэтому ТЫ позволяет пользователям создавать более-развитые приложения для IPC.

Однако ТЫ используется только в UNIX System V.3 и V.4, тогда как гнезда представлены во всех последних разновидностях UNIX (BSD 4.2, 4.3, 4.4 и UNIX System V.4). Более того, на сегодняшний день уже имеется множество IPC-приложений, построенных на основе использования гнезд. Следовательно, если главными факторами для разработчиков приложений являются мобильность и совместимость с уже существующими приложениями, им следует ориентироваться на гнезда, а не на ТЫ.

11.8. Заключение

В этой главе рассмотрены такие средства межпроцессного взаимодействия, как гнезда BSD UNIX и интерфейс транспортного уровня (ТЫ) UNIX System V.3/V.4. Гнезда и ТЫ более эффективны, чем сообщения, разделяемая память и семафоры, так как они позволяют взаимодействовать процессам.



ГЛАВА


Удаленные вызовы процедур

Удаленные вызовы процедур (Remote procedure calls, RPC) - это механизм, с помощью которого один процесс активизирует другой процесс на этой же или удаленной машине для выполнения какой-то функции от своего имени. RPC напоминает вызов локальной функции: процесс вызывает функцию и передает ей данные, а затем ожидает, когда она возвратит результат. Специфика заключается в том, что эту функцию вьшолняет другой процесс. Такое взаимодействие процессов обязательно протекает по схеме клиент/сервер, в которой процесс, активизирующий RPC, является клиентским, а процесс, выполняющий RPC-функцию,- серверным. Серверный процесс обеспечивает доступ к одной или нескольким сервисным функциям, которые могут вызываться его клиентами.

Удаленные вызовы процедур используются в сетевых приложениях для подключения к сетевым ресурсам других машин. Например, в распределенной базе данных серверным является процесс управления БД, обеспечивающий поиск и хранение данных в ее файлах. Клиентские процессы - внешние программы БД, которые позволяют пользователям запрашивать и обновлять данные. Клиентские процессы преобразуют команды пользователя в RPC и направляют их серверному процессу. Значения, возвращаемые RPC-функ-циями, сообщаются пользователю клиентскими процессами.

Рассмотрим еще один пример применения RPC: серверный процесс запускается на высокопроизводительном компьютере, а клиентские - на менее мощных. Когда клиентскому процессу нужно выполнить задание с большим объемом вычислений, он с помощью RPC активизирует серверный процесс, и задание выполняется на сервере. Таким образом обеспечивается более равномерная нагрузка на компьютеры и поддерживается приемлемый уровень производительности клиентского компьютера.



1 ... 67 68 69 [ 70 ] 71 72 73 ... 98

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика