Обмен сообщениями и импульсами в ОС QNX. Обмен сообщениями при стандартной организации модели "клиент-сервер", управляемой по запросу, страница 4

Префикс можно сделать сетевым. Глобальные имена процессов поддерживаются с помощью администратора gns (GNS - Global Name Service). Эта программа может быть запущена либо в серверном (опция –s), либо в клиентском (опция -c) режимах. При этом она регистрирует префикс /dev/name/gns_server или /dev/name/gns_client соответственно. Регистрация имени выполняется прикладной программой с помощью вышеупомянутой функции name_attach(). Для регистрации глобального префикса в аргументах этой функции задаётся флаг NAME_FLAG_ATTACH_GLOBAL. Префикс регистрируется или в каталоге /dev/name/global, или в каталоге /dev/name/local в зависимости от флага.

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

Рассмотрим программы сетевого взаимодействия.

Программа server2_net.c:

#include <errno.h>

#include <process.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <sys/dispatch.h>

#include <sys/neutrino.h>

int main (int argc, char *argv[]) {

name_attach_t   *channel; 

int rcvid;

char receive_buf[50], reply_buf[50];

channel = name_attach(NULL, argv[1], NAME_FLAG_ATTACH_GLOBAL);

while (1) {

// Принимаем сообщение из канала chid

rcvid = MsgReceive(channel->chid, &receive_buf, sizeof(receive_buf), NULL);

// Если не импульс, обрабатываем сообщение

if (rcvid) {

if (strlen(receive_buf)) {

// Выведем текст принятого сообщения

printf("Server: message from client \"%s\"\n", &receive_buf );

// Запишем в буфер ответа сообщение для клиента

strcpy(reply_buf, "Hello from server");

// Отправим ответ

printf("Server: send message \"%s\"\n", &reply_buf );

}

else {

strcpy(reply_buf, "ok");

}

MsgReply(rcvid, EOK, &reply_buf, sizeof(reply_buf));

}

}

// Уничтожаем префикс и канал

name_detach(channel, 0);

return EXIT_SUCCESS;

}

Зелёным цветом показаны изменения, внесённые в программу сервера для работы в сетевом варианте.

Программа клиентского приложения осталась прежней, за исключением добавления флага NAME_FLAG_ATTACH_GLOBAL в параметрах функции name_open().

На компьютере, на котором был запущен сервер (SPOcomp10), выполнили команду gns –s,  на компьютере клиента (SPOcomp11) - gns –c.

Результаты обмена сообщениями представлены на рис. 1.8.

server.bmp

gns_client.bmp

Рис. 1.8. Сообщения сервера и клиента

В результате был успешно произведён обмен сообщениями между клиентом и сервером, находящимися на разных узлах сети.

1.4. Обмен сообщениями на основе C-функций open, write, read

Пусть одна программа запишет информацию в файл, другая считает её оттуда.

Программа write.c:

#include <fcntl.h>

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

int main (int argc, char *argv[]) {

if (argc != 2) {

printf("Wrong number of arguments\n");

return EXIT_FAILURE;

}

char buf[50] = "Hello from writer";

int fd = open (argv[1], O_WRONLY | O_CREAT);

write(fd, buf, sizeof(buf));

close(fd);

return EXIT_SUCCESS;

}

Программа read.c:

#include <fcntl.h>

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

int main(int argc, char *argv[]) {

if (argc != 2) {

printf("Wrong number of arguments\n");

return EXIT_FAILURE;

}

int size_read;

char buf[50];

int fd = open(argv[1], O_RDONLY);

size_read = read(fd, buf, sizeof(buf));

if (size_read == -1) {

printf("Error reading %s", argv[1]);

return EXIT_FAILURE;

}

close(fd);

printf ("Text is \"%s\"\n", buf);

return EXIT_SUCCESS;

}