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

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

Жанры

Основы программирования в 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);

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

Третий. Том 5

INDIGO
5. Отпуск
Фантастика:
космическая фантастика
фантастика: прочее
5.00
рейтинг книги
Третий. Том 5

Лекарь

Щепетнов Евгений Владимирович
1. Истринский цикл
Фантастика:
фэнтези
8.24
рейтинг книги
Лекарь

Удар Молнии

Алексеев Сергей Трофимович
Детективы:
боевики
5.00
рейтинг книги
Удар Молнии

Кодекс Императора II

Сапфир Олег
2. Кодекс Императора
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Кодекс Императора II

Тактик

Земляной Андрей Борисович
2. Офицер
Фантастика:
альтернативная история
7.70
рейтинг книги
Тактик

Воронцов. Перезагрузка. Книга 5

Тарасов Ник
5. Воронцов. Перезагрузка
Фантастика:
попаданцы
альтернативная история
фэнтези
фантастика: прочее
6.00
рейтинг книги
Воронцов. Перезагрузка. Книга 5

Император Пограничья 6

Астахов Евгений Евгеньевич
6. Император Пограничья
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Император Пограничья 6

Анти-Ксенонская Инициатива

Вайс Александр
7. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
космоопера
5.00
рейтинг книги
Анти-Ксенонская Инициатива

Камень. Книга 4

Минин Станислав
4. Камень
Фантастика:
боевая фантастика
7.77
рейтинг книги
Камень. Книга 4

Мастер 11

Чащин Валерий
11. Мастер
Фантастика:
боевая фантастика
попаданцы
технофэнтези
аниме
фэнтези
5.00
рейтинг книги
Мастер 11

Московский гость

Литов Михаил
Детективы:
прочие детективы
5.00
рейтинг книги
Московский гость

Вперед в прошлое 7

Ратманов Денис
7. Вперед в прошлое
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Вперед в прошлое 7

Мастер 2

Чащин Валерий
2. Мастер
Фантастика:
фэнтези
городское фэнтези
попаданцы
технофэнтези
4.50
рейтинг книги
Мастер 2

Убивать чтобы жить 6

Бор Жорж
6. УЧЖ
Фантастика:
боевая фантастика
космическая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 6