Чтение онлайн

на главную - закладки

Жанры

UNIX: взаимодействие процессов

Стивенс Уильям Ричард

Шрифт:

Теперь мы можем переделать наш пример с клиентом и сервером, используя одну очередь сообщений с различными типами для разных адресатов. Эти программы используют следующее соглашение: сообщения с типом 1 адресованы серверу, а все остальные сообщения имеют тип, соответствующий идентификатору процесса адресата. При этом запрос клиента должен содержать его PID вместе с полным именем запрашиваемого файла, аналогично программе в разделе 4.8.

В листинге 6.12 приведен текст функции main сервера. Заголовочный файл svmsg.h был приведен в листинге 6.7. Создается единственная очередь сообщений (если она существует, ошибки не возникнет). Идентификатор этой очереди сообщений используется в качестве обоих аргументов при вызове функции server.

Листинг 6.12. Функция main сервера

//svmsgmpx1q/server_main.с

1 #include "svmsg.h"

2 void server(int, int);

3 int

4 main(int argc, char **argv)

5 {

6 int msqid;

7 msqid = Msgget(MQ_KEY1, SVMSG_MODE | IPC_CREAT);

8 server(msqid, msqid); /* одна очередь в обе стороны */

9 exit(0);

10 }

Функция server обеспечивает работу сервера. Ее текст приведен в листинге 6.13. Эта функция представляет собой комбинацию листинга 4.10 — нашего сервера FIFO, считывавшего команды, состоявшие из идентификатора процесса и полного имени файла, — и листинга 4.16, в котором использовались функции mesg_send и mesg_recv. Обратите внимание, что идентификатор процесса, отправляемый клиентом, используется в качестве типа для всех сообщений, отправляемых сервером этому клиенту. Эта функция представляет собой бесконечный цикл, в котором считываются запросы клиентов и отсылаются запрошенные файлы. Этот сервер является последовательным (см. раздел 4.9).

В листинге 6.14 приведен текст функции main клиента. Клиент открывает очередь сообщений, которая должна была быть создана сервером заранее.

Функция client, текст которой дан в листинге 6.15, обеспечивает всю обработку со стороны клиента. Эта функция представляет собой комбинацию программ из листингов 4.11 и 4.15. В первой программе клиент отсылал свой идентификатор и полное имя файла, а во второй программе использовались функции mesg_send и mesg_recv. Обратите внимание, что тип сообщений, запрашиваемых функцией mesg_recv, совпадает с идентификатором процесса клиента.

Функции client и server используют функции mesg_send и mesg_recv из листингов 6.9 и 6.11.

Листинг 6.13. Функция server

//svmsgmpx1q/server.c

1 #include "mesg.h"

2 void

3 server(int readfd, int writefd)

4 {

5 FILE *fp;

6 char *ptr;

7 pid_t pid;

8 ssize_t n;

9 struct mymesg mesg;

10 for (;;) {

11 /* считывание полного имени из канала IPC */

12 mesg.mesg_type = 1:

13 if ((n = Mesg_recv(readfd, &mesg)) == 0) {

14 err_msg("pathname missing");

15 continue;

16 }

17 mesg.mesg_data[n] = '\0'; /* полное имя */

18 if ((ptr = strchr(mesg.mesg_data, ' ')) == NULL) {

19 err_msg("bogus request: %s", mesg.mesg_data);

20 continue;

21 }

22 *ptr++ =0; /* ptr = полное имя */

23 pid = atol(mesg.mesg_data);

24 mesg.mesg_type = pid; /* для обратных сообщений */

25 if ((fp = fopen(ptr, "r")) == NULL) {

26 /* 4error: must tell client */

27 snprintf(mesg.mesg_data + n, sizeof(mesg.mesg_data) – n,

28 ": can't open. %s\n", strerror(errno));

29 mesg.mesg_len – strlen(ptr);

30 memmove(mesg.mesg_data, ptr, mesg.mesg_len);

31 Mesg_send(writefd, &mesg);

32 } else {

33 /* файл открыт, копируем клиенту */

34 while (Fgets(mesg.mesg_data, MAXMESGDATA, fp) != NULL) {

35 mesg.mesg_len = strlen(mesg.mesg_data);

36 Mesg_send(writefd, &mesg);

37 }

38 Fclose(fp);

39 }

40 /* сообщение нулевой длины заканчивает связь */

41 mesg.mesg_len = 0;

42 Mesg_send(writefd, &mesg);

43 }

44 }

Листинг 6.14. Функция main клиента

//svmsgmpx1q/client_main.c

1 #include "svmsg.h"

2 void client(int, int);

3 int

4 main(int argc, char **argv)

5 {

6 int msqid;

7 /* сервер должен был создать очередь */

8 msqid = Msgget(MQ_KEY1, 0);

9 client(msqid, msqid); /* одна очередь в обе стороны */

10 exit(0);

11 }

Листинг 6.15. Функция client

//svmsgmpx1q/client.с

1 #include "mesg.h"

2 void

Поделиться:
Популярные книги

Барон

Первухин Андрей Евгеньевич
5. Ученик
Фантастика:
фэнтези
5.60
рейтинг книги
Барон

Заботы Элли Рэйт

Ром Полина
Фантастика:
попаданцы
фэнтези
6.25
рейтинг книги
Заботы Элли Рэйт

Источник

Билик Дмитрий Александрович
11. Бедовый
Фантастика:
юмористическое фэнтези
городское фэнтези
мистика
7.00
рейтинг книги
Источник

Ермак. Телохранитель

Валериев Игорь
2. Ермак
Фантастика:
альтернативная история
7.50
рейтинг книги
Ермак. Телохранитель

Ярар. Начало

Грехов Тимофей
1. Ярар
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Ярар. Начало

Ким

Киплинг Редьярд Джозеф
Приключения:
исторические приключения
7.62
рейтинг книги
Ким

Двойник короля 20

Скабер Артемий
20. Двойник Короля
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Двойник короля 20

Атаман. Гексалогия

Корчевский Юрий Григорьевич
Фантастика:
попаданцы
альтернативная история
историческое фэнтези
8.15
рейтинг книги
Атаман. Гексалогия

Дважды одаренный. Том IV

Тарс Элиан
4. Дважды одаренный
Фантастика:
городское фэнтези
альтернативная история
аниме
7.00
рейтинг книги
Дважды одаренный. Том IV

Сирийский рубеж 2

Дорин Михаил
6. Рубеж
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Сирийский рубеж 2

Дважды одаренный. Том VII

Тарс Элиан
7. Дважды одаренный
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Дважды одаренный. Том VII

Антимаг

Гедеон Александр и Евгения
1. Антимаг
Фантастика:
фэнтези
6.95
рейтинг книги
Антимаг

Лев Толстой

Шкловский Виктор Борисович
363. Жизнь замечательных людей
Документальная литература:
биографии и мемуары
5.00
рейтинг книги
Лев Толстой

Неучтенный элемент. Том 11

NikL
11. Антимаг. Вне системы
Фантастика:
фэнтези
5.00
рейтинг книги
Неучтенный элемент. Том 11