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

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

Жанры

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

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

Я все еще граф. Книга IX

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

Мастер 3

Чащин Валерий
3. Мастер
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Мастер 3

Рассвет русского царства

Грехов Тимофей
1. Новая Русь
Документальная литература:
историческая литература
5.00
рейтинг книги
Рассвет русского царства

Сфирот

Прокофьев Роман Юрьевич
8. Стеллар
Фантастика:
боевая фантастика
рпг
6.92
рейтинг книги
Сфирот

Газлайтер. Том 38

Володин Григорий Григорьевич
38. История Телепата
Фантастика:
городское фэнтези
аниме
попаданцы
6.20
рейтинг книги
Газлайтер. Том 38

Кодекс Охотника. Книга XIX

Винокуров Юрий
19. Кодекс Охотника
Фантастика:
фэнтези
5.00
рейтинг книги
Кодекс Охотника. Книга XIX

Третий. Том 4

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

Очкарик

Афанасьев Семён
Фантастика:
фэнтези
5.75
рейтинг книги
Очкарик

Газлайтер. Том 20

Володин Григорий Григорьевич
20. История Телепата
Фантастика:
боевая фантастика
аниме
попаданцы
5.25
рейтинг книги
Газлайтер. Том 20

Ведун

Сухов Александр Евгеньевич
1. Второй шанс
Фантастика:
фэнтези
боевая фантастика
альтернативная история
5.00
рейтинг книги
Ведун

Газлайтер. Том 23

Володин Григорий Григорьевич
23. История Телепата
Фантастика:
боевая фантастика
попаданцы
аниме
5.25
рейтинг книги
Газлайтер. Том 23

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

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

Газлайтер. Том 27

Володин Григорий Григорьевич
27. История Телепата
Фантастика:
боевая фантастика
попаданцы
аниме
5.25
рейтинг книги
Газлайтер. Том 27

Тринадцатый VII

NikL
7. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
5.25
рейтинг книги
Тринадцатый VII