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

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

Жанры

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

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

Вернувшийся: Первые шаги. Том II

Vector
2. Вернувшийся
Фантастика:
боевая фантастика
космическая фантастика
рпг
5.00
рейтинг книги
Вернувшийся: Первые шаги. Том II

Князь Целитель 4

Ткачев Андрей Юрьевич
4. Князь Целитель
Фантастика:
боевая фантастика
городское фэнтези
аниме
фэнтези
5.00
рейтинг книги
Князь Целитель 4

Дитя прибоя

Трофимов Ерофей
Дитя прибоя
Фантастика:
боевая фантастика
попаданцы
фэнтези
5.00
рейтинг книги
Дитя прибоя

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

Володин Григорий
9. История Телепата
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Газлайтер. Том 9

Неучтенный элемент. Том 2

NikL
2. Антимаг. Вне системы
Фантастика:
городское фэнтези
фэнтези
5.00
рейтинг книги
Неучтенный элемент. Том 2

Неучтенный элемент. Том 6

NikL
6. Антимаг. Вне системы
Фантастика:
фэнтези
5.00
рейтинг книги
Неучтенный элемент. Том 6

Одержимая (авторский сборник)

Дяченко Марина и Сергей
Фантастика:
фэнтези
научная фантастика
7.80
рейтинг книги
Одержимая (авторский сборник)

Древесный маг Орловского княжества 9

Павлов Игорь Васильевич
9. Орловское княжество
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Древесный маг Орловского княжества 9

Собрание сочинений. Т. 20. Плодовитость

Золя Эмиль
Проза:
классическая проза
5.00
рейтинг книги
Собрание сочинений. Т. 20. Плодовитость

Элизиум. Аликс и монеты

Андерсон Александр
1. Элизиум
Фантастика:
фэнтези
сказочная фантастика
8.98
рейтинг книги
Элизиум. Аликс и монеты

Вернувшийся: Корпорация. Том III

Vector
3. Вернувшийся
Фантастика:
космическая фантастика
боевая фантастика
рпг
5.00
рейтинг книги
Вернувшийся: Корпорация. Том III

Тринадцатый VI

NikL
6. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Тринадцатый VI

Эволюционер из трущоб. Том 3

Панарин Антон
3. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
6.00
рейтинг книги
Эволюционер из трущоб. Том 3

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

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