"Server Warning:- failed to respond to %d\n", resp.client_pid);
break;
}
} else {
resp.response = r_find_no_more;
}
} while (resp.response == r_success);
break;
default:
resp.response = r_failure;
break;
} /* switch */
sprintf(resp.error_text,
"Command failed:\n\t%s\n", strerror(save_errno));
if (!send_resp_to_client(resp)) {
fprintf(stderr,
"Server Warning:- failed to respond to %d\n", resp.client_pid);
}
end_resp_to_client;
return;
}
Прежде
чем рассматривать действующую реализацию канала, давайте обсудим последовательность событий, которые должны произойти для передачи данных между клиентским и серверным процессами. На рис. 13.9 показан запуск обоих, и клиентского, и серверного, процессов, а также то, как они образуют петлю во время обработки команд и ответов.
В этой реализации ситуация немного сложнее, т.к. в запросе на поиск клиент передает серверу одну команду и затем ждет один или несколько ответов от
сервера. Это усложняет программу, особенно клиентскую часть.
Рис. 13.9
Канал
Далее показан файл реализации канала pipe_imp.с, в котором содержатся клиентские и серверные функции.
Примечание
Как вы видели в главе 10, может быть определено символическое имя DEBUG_TRACE для того, чтобы показать последовательность вызовов, в которых клиентский и серверный процессы передают друг другу сообщения.
Заголовочный файл для реализации канала
1. Прежде всего, директивы
#include
:
#include "cd_data.h"
#include "cliserv.h"
2. Вы также определяете в файле программы несколько значений, нужных вам в разных функциях:
Далее нужно рассмотреть функции серверной стороны. В следующем разделе показаны функции, открывающие и закрывающие именованный канал и читающие сообщения от клиентов. В следующем за ним разделе приведен программный код, который открывает и закрывает клиентские каналы и пересылает по ним сообщения, основываясь на идентификаторе процесса, который клиент включает в свое сообщение.
Функции сервера
1. Подпрограмма
server_starting
создает именованный канал, из которого сервер будет считывать команды. Далее она открывает канал для чтения. Этот вызов
open
будет блокировать выполнение, пока клиент не откроет канал для записи. Используйте режим блокировки для того, чтобы сервер мог выполнить блокировку вызовов
read
в канале в ожидании отправляемых ему команд.
int server_starting(void) {
#if DEBUG_TRACE
printf("%d server_starting\n", getpid);
#endif
unlink(SERVER_PIPE);
if (mkfifo(SERVER_PIPE, 0777) == -1) {
fprintf(stderr, "Server startup error, no FIFO created\n");
return(0);
}
if ((server_fd = open(SERVER_PIPE, O_RDONLY)) == -1) {
if (errno == EINTR) return(0);
fprintf(stderr, "Server startup error, no FIFO opened\n");