Вход/Регистрация
UNIX: взаимодействие процессов
вернуться

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

Шрифт:

8 /* считывание полного имени */

9 Fgets(mesg.mesg_data, MAXMESGDATA, stdin);

10 len = strlen(mesg.mesg_data);

11 if (mesg.mesg_data[len-1] == '\n')

12 len--; /* удаление перевода строки из fgets */

13 mesg.mesg_len = len;

14 mesg.mesg_type = 1;

15 /* запись полного имени в канал IPC */

16 Mesg_send(writefd, &mesg);

17 /* считывание из канала IPC. запись в stdout */

18 while ( (n = Mesg_recv(readfd, &mesg)) > 0)

19 Write(STDOUT_FILENO, mesg.mesg_data, n);

20 }

Считывание имени файла и отправка его серверу

8-16 Полное имя считывается из стандартного потока ввода и затем отправляется на сервер с помощью функции mesg_send.

Считывание содержимого файла или сообщения об ошибке от сервера

17-19 Клиент вызывает функцию mesg_recv в цикле, считывая все приходящие от сервера сообщения. По соглашению, когда mesg_recv возвращает нулевую длину сообщения, это означает конец передаваемых сервером данных. Мы увидим, что сервер добавляет символ перевода строки к каждому сообщению, отправляемому клиенту, поэтому пустая строка будет иметь длину сообщения 1. В листинге 4.16 приведен текст функции-сервера.

Листинг 4.16. Функция server, использующая сообщения

//pipemesg/server.c

1 #include "mesg.h"

2 void

3 server(int readfd, int writefd)

4 {

5 FILE *fp;

6 ssize_t n;

7 struct mymesg mesg;

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

9 mesg.mesg_type = 1;

10 if ((n = Mesg_recv(readfd, &mesg)) == 0)

11 err_quit("pathname missing");

12 mesg.mesg_data[n] = '\0'; /* полное имя, завершающееся 0 */

13 if ((fp = fopen(mesg.mesg_data, "r")) == NULL) {

14 /* ошибка, нужно сообщить клиенту */

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

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

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

18 Mesg_send(writefd, &mesg);

19 } else {

20 /* файл успешно открыт, передача данных */

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

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

23 Mesg_send(writefd, &mesg);

24 }

25 Fclose(fp);

26 }

27 /* отправка сообщения нулевой длины для обозначения конца связи */

28 mesg.mesg_len = 0;

29 Mesg_send(writefd, &mesg);

30 }

Считывание имени файла из канала IPC, открытие файла

8-18 Сервер принимает от клиента имя файла. Хотя значение mesg_type, равное 1, нигде не используется (оно затирается функцией mesg_recv из листинга 4.14), мы будем использовать ту же функцию при работе с очередями сообщений System V (листинг 6.8), а в данном случае в этом значении уже возникает потребность (см., например, листинг 6.11). Стандартная функция ввода-вывода fopen открывает файл, что отличается от листинга 4.3, где вызывалась функция open для получения дескриптора файла. Причина, по которой мы воспользовались fopen, заключается в том, что в этой пpoгрaммe мы пользуемся библиотечной функцией fgets для считывания содержимого файла построчно и затем отправляем клиенту строку за строкой.

Отправка файла клиенту

19-26 Если вызов fopen оказывается успешным, содержимое файла считывается с помощью функции fgets и затем отправляется клиенту построчно. Сообщение с нулевой длиной означает конец файла.

При использовании пpoгрaммныx каналов или FIFO мы могли бы также закрыть канал IPC, чтобы дать клиенту знать о том, что передача файла завершена. Однако мы используем передачу сообщения нулевой длины, потому что другие типы IPC не поддерживают концепцию конца файла.

  • Читать дальше
  • 1
  • ...
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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