if (result)

   printf('Менеджер ресурсов не смог обработать'

    ' сообщение result = %i ', result);

 }

}

/********************************************************************

Обработчик приватных сообщений, то есть сообщений, заголовок которых

укладывается в диапазон, указанный при вызове функции message_attach()

********************************************************************/

int PrivatHandler(message_context_t* ctp, int code,

 unsigned flags, void* handle) {

 char Buffer[MESSIZE_MAX];

 printf('получено приватное сообщение тип %x от'

  ' '%s' ', code, IdLabelParse(code));

 printf('Вот это сообщение <<%s>> ',

  (char *)(ctp->msg) + 4);

 strcpy(Buffer, 'Клиенту: да, я такой');

 MsgReply(ctp->rcvid, EOK, Buffer, sizeof(Buffer));

 return(0);

}

/********************************************************************

Функция пользовательской библиотеки, определяющая инвентаризационное

имя процесса по его инвентаризационной метке

********************************************************************/

char* IdLabelParse(int id) {

 struct IdLabel_t Inventory;

 int i = 0;

 while (IdLabel[i].id != id && i < ALLNUM_MYPROC) i++;

 if (i == ALLNUM_MYPROC) return Anonymous;

 else return(IdLabel[i].name);

}

Использование менеджера службы глобальных имен

Начиная с QNX версии 6.3 сервис глобальных имен, обеспечиваемый GNS-менеджером службы (утилитой gns), действует в сети. Используя этот сервис, нет необходимости организовывать программу как полноценный менеджер ресурсов, при этом приложение-сервер может объявлять свою службу, а приложения-клиенты могут отыскивать и использовать службы через QNET-сеть без знания таких частностей, как, например, где эта служба располагается и кто ее обеспечивает. Подробно о сервисе глобальных имен см. в [4].

Для того чтобы развернуть этот сервис, необходимо в режиме сервера запустить менеджер службы глобальных имен на том узле, где должно работать наше приложение-сервер. В режиме сервера GNS- менеджер выступает в роли некой центральной базы данных, хранящей объявленные службы, и обрабатывает запросы на поиск и установление связи с ними. На узле же, где располагается клиент, запускаем менеджер в режиме клиента, при этом он передает запросы объявления, поиска и установки связи между локальным (то есть расположенным на этом же узле) приложением-клиентом и сервером (серверами) gns.

Серверный узел:

# gns -s

Клиентский узел (узлы):

# gns -с

В результате на узлах, где запущены службы глобальных имен, появятся имена /dev/name/global и /dev/name/local. Каждый узел, на котором запущен gns- клиент или сервер, в одной и той же сети имеет один и тот же вид пространства имен на /dev/name/global. Каждый узел имеет локальное пространство имен /dev/name/local, являющееся локальным для данной машины и отличающееся от локального пространства имен на другой машине. (Кстати, помимо имен global и local под /dev/name/ появится еще имя gns_server или gns_local — имя, под которым регистрируется сам GNS-менеджер.)

Существует несколько функций API, относящихся к службе глобальных имен: name_attach() , name_open() и name_close(). Программисты, знакомые с QNX 4, сразу «узнают» в них аналоги известных им функций qnx_name_attach(), qnx_name_open() и qnx_name_close(). Приложения используют эти функции для объявления имени службы, связи со службой и отсоединения от службы.

Итак, чтобы объявить свое имя глобально в сети, приложение-сервер должно на узле, где в режиме сервера функционирует менеджер службы глобальных имен, объявить свою службу, выполнив вызов:

if (!(NameServer = name_attach(NULL, 'MyService', NAME_FLAG_ATTACH_GLOBAL)))

 return EXIT_FAILURE;

Флаг NAME_FLAG_ATTACH_GLOBAL указывает, что приложение-сервер объявляет свое имя глобально — в сети. Приложение, которое может подсоединить службу глобально, должно иметь право доступа root. После выполнения этого вызова в директории /dev/name/global появится подсоединенное имя MyService (если бы третий аргумент вызова был установлен в ноль, это имя оказалось бы подсоединенным к /dev/name/local и было бы доступно только локально).

Регистрируя имя в пространстве глобальных имен, функция name_attach() создает канал, идентификатор которого она возвращает в составе структуры NameServer. Отметим, что этот канал создается с определенными установленными флагами, задающими соответствующие действия системе:

• _NTO_CHF_UNBLOCK — доставлять владельцу канала импульс с кодом _PULSE_CODE_UNBLOCK и значением rcvid каждый раз, когда Reply- блокированный клиент попытается разблокироваться (скажем, по получению сигнала или по таймеру);

• _NTO_CHF_DISCONNECT — доставлять владельцу канала импульс с кодом _PULSE_CODE_DISCONNECT, когда от процесса отсоединились все установленные соединения клиента (клиент выполнил name_close() на каждый свой name_open() к имени сервера либо вообще умер);

• _NTO_CHF_COID_DISCONNECT — доставлять владельцу канала импульс с кодом _PULSE_CODE_COIDDEATH и значением coid (идентификатора соединения) для каждого соединения по этому каналу, когда канал закрывается.

Теперь, после создания канала, сервер может становиться на прием сообщений от клиентов:

rcvid = MsgReceive(NameServer->chid, &MsgBuf, sizeof MsgBuf);

Однако может так случиться, что клиент пошлет не непосредственное сообщение для сервера, а

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату
×