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

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

Жанры

Основы программирования в Linux
Шрифт:

 }

 return(1);

}

2. Когда сервер завершает работу, он удаляет именованный канал, для того чтобы клиенты могли установить, что нет действующего сервера.

void server_ending(void) {

#if DEBUG_TRACE

 printf("%d:- server_ending\n", getpid);

#endif

 (void)close(server_fd);

 (void)unlink(SERVER_PIPE);

}

3. Функция

read_request_from_client
будет блокировать чтение в серверном канале до тех пор, пока клиент не запишет в него сообщение.

int read_request_from_client(message_db_t *rec_ptr) {

 int return_code = 0;

 int read_bytes;

#if DEBUG_TRACE

 printf("%d :- read_request_from_client\n", getpid);

#endif

 if (server_fd != -1) {

read_bytes = read(server_fd, rec_ptr, sizeof(*rec_ptr));

...

 }

 return(return_code);

}

4. В особом случае, когда ни у одного клиента нет канала, открытого для записи, вызов

read
вернет 0, т.е. он обнаружит EOF (метку конца файла). Затем сервер закроет канал и откроет его снова так, что канал блокируется до тех пор, пока клиент также не откроет канал. Выполняется то же, что и при первом запуске сервера; вы инициализировали сервер повторно. Вставьте этот программный код в предыдущую функцию. 

if (read_bytes == 0) {

 (void)close(server_fd);

 if ((server_fd = open(SERVER_PIPE, O_RDONLY)) == -1) {

if (errno != EINTR) {

fprintf(stderr, "Server error, FIFO open failed\n");

}

return(0);

 }

 read_bytes = read(server_fd, rec_ptr, sizeof(*rec_ptr));

}

if (read_bytes == sizeof(*rec_ptr)) return_code = 1;

Сервер — это единственный процесс, способный одновременно обслуживать множество клиентов. Поскольку каждый клиент применяет свой канал для получения ответов, адресованных ему, сервер, для того чтобы отправить ответы разным клиентам, должен писать в разные каналы. Поскольку файловые дескрипторы — это ограниченный ресурс, сервер открывает клиентский канал для записи только тогда, когда у него есть данные для отправки.

В программном коде открытие клиентского канала, запись в него и закрытие канала разделены на три отдельные функции. Когда вы возвращаете многочисленные результаты поиска, такой подход необходим, для того чтобы можно было открыть канал один раз, записать в него множество ответов и затем снова закрыть канал.

Прокладка каналов

1. Сначала

откройте канал клиента.

int start_resp_to_client(const message_db_t mess_to_send) {

#if DEBUG_TRACE

 printf("%d :- start_resp_to_client\n", getpid);

#endif

 (void)sprintf(client_pipe_name, CLIENT_PIPE,

mess_to_send.client_pid);

 if ((client_fd = open(client_pipe_name, O_WRONLY)) == -1) return(0);

 return(1);

}

2. Все сообщения отправляются с помощью данной функции. Соответствующие клиентские функции, которые принимают сообщение, вы увидите позже.

int send_resp_to_client(const message_db_t mess_to_send) {

 int write_bytes;

#if DEBUG_TRACE

 printf("%d :- send_resp_to_client\n", getpid);

#endif

 if (client_fd == -1) return(0);

 write_bytes = write(client_fd, &mess_to_send, sizeof(mess_to_send));

 if (write_bytes != sizeof(mess_to_send)) return(0);

 return(1);

}

3. В заключение закройте клиентский канал.

void end resp_to_client(void) {

#if DEBUG_TFACE

 printf("%d :- end_resp_to_client\n", getpid);

#endif

 if (client_fd != -1) {

(void)close(сlient_fd);

client_fd = -1;

 }

}

Функции на стороне клиента

Дополнение к серверу — клиентские функции в файле pipe_imp.c. Они очень похожи на серверные функции за исключением функции с интригующим именем

send_mess_to_server
.

Клиентские функции

1. После проверки доступности сервера функция

client_starting
инициализирует канал клиентской стороны.

int client_starting(void) {

#if DEBUG_TFACE

 printf("%d client_starting\n", getpid);

#endif

 mypid = getpid;

 if ((server_fd = open(SERVER_PIPE, O_WRONLY)) == -1) {

fprintf(stderr, "Server not running\n");

return(0);

 }

 (void)sprintf(client pipe name, CLIENT_PIPE, mypid);

 (void)unlink(client_pipe_name);

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

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

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

Меченосцы

Сенкевич Генрик
Проза:
историческая проза
6.25
рейтинг книги
Меченосцы

"Фантастика 2026-91". Компиляция. Книги 1-9

Неженцева Екатерина
Фантастика 2026. Компиляция
Фантастика:
боевая фантастика
фэнтези
5.00
рейтинг книги
Фантастика 2026-91. Компиляция. Книги 1-9

Похвали меня

Кейт Сара
Любовные романы:
зарубежные любовные романы
5.00
рейтинг книги
Похвали меня

Зарубежный детектив (1989)

Чейз Джеймс Хедли
Проза:
современная проза
5.80
рейтинг книги
Зарубежный детектив (1989)

Годы странствий

Чулков Георгий Иванович
Документальная литература:
биографии и мемуары
6.25
рейтинг книги
Годы странствий

Радуга

Стоун Кэтрин
Любовные романы:
современные любовные романы
7.71
рейтинг книги
Радуга

Нам здесь (не) жить

Зонин Сергей
2. Насуверс
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Нам здесь (не) жить

Битва королей

Мартин Джордж Р.Р.
Фантастика:
фэнтези
5.00
рейтинг книги
Битва королей

Жертва

Привалов Сергей
2. Звездный Бродяга
Фантастика:
боевая фантастика
космическая фантастика
рпг
попаданцы
6.25
рейтинг книги
Жертва

"Фантастика 2025-79". Компиляция. Книги 1-32

Буланова Наталья Александровна
Фантастика 2025. Компиляция
Фантастика:
боевая фантастика
попаданцы
альтернативная история
фэнтези
5.00
рейтинг книги
Фантастика 2025-79. Компиляция. Книги 1-32

Хватательная рука

Нивен Ларри
2. Мошкиты
Фантастика:
научная фантастика
6.00
рейтинг книги
Хватательная рука

Точка Бифуркации XVI

Смит Дейлор
16. ТБ
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Точка Бифуркации XVI

Алексей Михайлович

Соловьев Всеволод Сергеевич
4. Романовы. Династия в романах
Проза:
историческая проза
5.50
рейтинг книги
Алексей Михайлович