Вход/Регистрация
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 }

  • Читать дальше
  • 1
  • ...
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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