Читать «UNIX: взаимодействие процессов» онлайн - страница 37
Уильям Ричард Стивенс
Функция client приведена в листинге 4.2.
Листинг 4.2. Функция client для приложения типа клиент-сервер с двумя каналами
//pipe/client.с
1 #include "unpipc.h"
2 void
3 client(int readfd, int writefd)
4 {
5 size_t len;
6 ssize_t n;
7 char buff[MAXLINE];
8 /* получение полного имени файла */
9 Fgets(buff, MAXLINE, stdin);
10 len = strlen(buff); /* fgets() гарантирует завершающий нулевой байт */
11 if (buff[Len-l] ==
12 len--; /* удаление перевода строки из fgets() */
13 /* запись полного имени в канал IPC */
14 Write(writefd, buff, len);
15 /* считывание из канала, вывод в stdout */
16 while ((n = Read(readfd, buff, MAXLINE)) > 0)
17 Write(STDOUT_FILENO, buff, n);
18 }
Считывание полного имени из стандартного потока ввода
8-14 Полное имя файла считывается из стандартного потока ввода и записывается в канал после удаления завершающего символа перевода строки, возвращаемого функцией fgets.
Копирование из канала в стандартный поток вывода
15-17 Затем клиент считывает все, что сервер направляет в канал, и записывает эти данные в стандартный поток вывода. Ожидается, что это будет содержимое файла, но в случае его отсутствия будет принято и записано в стандартный поток вывода сообщение об ошибке.
В листинге 4.3 приведена функция server.
Листинг 4.3. Функция server для приложения клиент-сервер с двумя каналами
//pipe/server.c
1 #include "unpipc.h"
2 void
3 server(int readfd, int writefd)
4 {
5 int fd;
6 ssize_t n;
7 char buff[MAXLINE+1];
8 /* получение полного имени из канала IPC */
9 if ((n = Read(readfd, buff, MAXLINE)) == 0)
10 err_quit("end-of-file while reading pathname"):
11 buff[n] = '\0'; /* полное имя завершается 0 */
12 if ((fd = open(buff, O_RDONLY)) < 0) {
13 /* 4error: must tell client */
14 snprintf(buff + n, sizeof(buff) – n, ": can't open. %s\n".
15 strerror(errno)):
16 n = strlen(buff);
17 Write(writefd, buff, n);
18 } else {
19 /* файл успешно открыт и копируется в канал */
20 while ( (n = Read(fd, buff, MAXLINE)) > 0)
21 Write(writefd, buff, n);
22 Close(fd);
23 }
24 }
Считывание полного имени файла из канала
8-11 Записанное в канал клиентом имя файла считывается сервером и дополняется завершающим символом с кодом 0 (null-terminated). Обратите внимание, что функция read возвращает данные, как только они помещаются в поток, не ожидая накопления некоторого их количества (MAXLINE в данном примере).
Открытие файла, обработка возможной ошибки
12-17 Файл открывается для чтения и при возникновении ошибки сообщение о ней возвращается клиенту с помощью канала. Для получения строки с соответствующим значению переменной errno сообщением об ошибке вызывается функция strerror (в книге [24, с. 690-691] вы найдете более подробный рассказ об этой функции).
Копирование из файла в канал
18-23 При успешном завершении работы функции open содержимое файла копируется в канал.