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

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

Жанры

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

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

Мятежник

Прокофьев Роман Юрьевич
4. Стеллар
Фантастика:
боевая фантастика
7.39
рейтинг книги
Мятежник

Виконт. Книга 2. Обретение силы

Юллем Евгений
2. Псевдоним `Испанец`
Фантастика:
боевая фантастика
попаданцы
рпг
7.10
рейтинг книги
Виконт. Книга 2. Обретение силы

Воронцов. Перезагрузка. Книга 5

Тарасов Ник
5. Воронцов. Перезагрузка
Фантастика:
попаданцы
альтернативная история
фэнтези
фантастика: прочее
6.00
рейтинг книги
Воронцов. Перезагрузка. Книга 5

Телохранитель Генсека. Том 3

Алмазный Петр
3. Медведев
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Телохранитель Генсека. Том 3

Законы Рода. Том 8

Мельник Андрей
8. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Законы Рода. Том 8

Черный Маг Императора 8

Герда Александр
8. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 8

Я уже барон

Дрейк Сириус
2. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я уже барон

Наследие Маозари 3

Панежин Евгений
3. Наследие Маозари
Фантастика:
рпг
аниме
5.00
рейтинг книги
Наследие Маозари 3

Дочь моего друга

Тоцка Тала
2. Айдаровы
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Дочь моего друга

Хозяин Теней 7

Петров Максим Николаевич
7. Безбожник
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Хозяин Теней 7

На границе империй. Том 10. Часть 4

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 4

Офицер

Земляной Андрей Борисович
1. Офицер
Фантастика:
боевая фантастика
7.21
рейтинг книги
Офицер

Трапеция

Брэдли Мэрион Зиммер
Проза:
современная проза
5.00
рейтинг книги
Трапеция

Адепт. Том 1. Обучение

Бубела Олег Николаевич
6. Совсем не герой
Фантастика:
фэнтези
9.27
рейтинг книги
Адепт. Том 1. Обучение