unsigned flags, void* handle) {
char Buffer[MESSIZE_MAX];
printf("получено приватное сообщение тип %x от"
" \"%s\"\n", code, IdLabelParse(code));
printf("Вот это сообщение <<%s>>\n",
(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
Для того чтобы развернуть этот сервис, необходимо в режиме сервера запустить менеджер службы глобальных имен на том узле, где должно работать наше приложение-сервер. В режиме сервера GNS-менеджер выступает в роли некой центральной базы данных, хранящей объявленные службы, и обрабатывает запросы на поиск и установление связи с ними. На узле же, где располагается клиент, запускаем менеджер в режиме клиента, при этом он передает запросы объявления, поиска и установки связи между локальным (то есть расположенным на этом же узле) приложением-клиентом и сервером (серверами)
gns
Серверный узел:
# gns -s
Клиентский узел (узлы):
# gns -с
В результате на узлах, где запущены службы глобальных имен, появятся имена
/dev/name/global
/dev/name/local
/dev/name/global
/dev/name/local
global
local
/dev/name/
gns_server
gns_local
Существует несколько функций API, относящихся к службе глобальных имен:
name_attach()
name_open()
name_close()
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
•
_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);
Однако может так случиться, что клиент пошлет не непосредственное сообщение для сервера, а выполнит, скажем, чтение, что, по сути, тоже является отосланным сообщением. Поэтому при получении сообщений необходимо производить их «фильтрацию»:
if (MsgBuf.hdr_type >= _IO_BASE && Buffer.hdr.type <= _IO_MAX) {