1. Прежде всего, вам нужен заголовочный файл client.h, в котором определены данные, общие для серверных и клиентских программ. В приложение также для удобства включены требуемые системные заголовочные файлы.
#include
#include
#include
#include
#include
#include
#include
#include
#define SERVER_FIFO_NAME "/tmp/serv_fifo"
#define CLIENT_FIFO_NAME "/tmp/cli_%d_fifo"
#define BUFFER_SIZE 20
struct data_to_pass_st {
pid_t client_pid;
char some_data[BUFFER_SIZE - 1];
};
2. Теперь займемся серверной программой server.c. В этом разделе вы создаете и затем открываете канал сервера. Он задается в режиме "только для чтения" и с блокировкой. После засыпания (из демонстрационных соображений) сервер читает данные от клиента, у которого есть структура типа data_to_pass_st.
#include "client.h"
#include
int main() {
int server_fifo_fd, client fifo_fd;
struct data_to_pass_st my_data;
int read_res;
char client_fifo[256];
char *tmp_char_ptr;
mkfifo(SERVER_FIFO_NAME, 0777);
server_fifo_fd = open(SERVER_FIFO_NAME, O_RDONLY);
if (server_fifo_fd == -1) {
fprintf(stderr, "Server fifo failure\n");
exit(EXIT_FAILURE);
}
sleep(10); /* для целей демонстрации разрешает клиентам создать очередь */
do {
read_res = read(server_fifo_fd, &my_data, sizeof(my_data));
if (read res > 0) {
3. На следующем этапе вы выполняете некоторую обработку данных, только что полученных от клиента: преобразуете все символы в некоторых данных в прописные и соединяете CLIENT_FIFO_NAME с полученным идентификатором client_pid.
tmp_char_ptr = my_data.some_data;
while (*tmp_char_ptr) {
*tmp_char_ptr = toupper(* tmp_char_ptr);
tmp_char_ptr++;
}
sprintf(client_fifo, CLIENT_FIFO_NAME, my_data.client_pid);
4. Далее отправьте обработанные данные назад, открыв канал клиентской программы в режиме "только для записи" и с блокировкой. В заключение закройте серверный FIFO с помощью закрытия файла и отсоединения FIFO.
client_fifo_fd = open(client_fifo, O_WRONLY);
if (client_fifo_fd ! = -1) {
write(client_fifo_fd, &my_data, sizeof(my_data));
close(client_fifo_fd);
}
}
} while (read_res > 0);
close(server_fifo_fd);
unlink(SERVER_FIFO_NAME);
exit(EXIT_SUCCESS);
}
5. Далее приведена клиентская программа client.с. В первой части этой программы FIFO сервера, если он уже существует, открывается как файл. Далее программа получает идентификатор собственного процесса, который формирует некие данные, которые будут отправляться на сервер. Создается FIFO клиента, подготовленный для следующего раздела.
#include "client.h"
#include
int main() {
int server_fifo_fd, client_fifo_fd;
struct data_to_pass_st my_data;
int times_to_send;
char client_fifo[256];
server_fifo_fd = open(SERVER_FIFO_NAME, O_WRONLY);
if (server_fifo_fd == -1) {
fprintf (stderr, "Sorry, no server\n");
exit(EXIT_FAILURE);
}
my_data.client_pid = getpid();
sprintf(client_fifo, CLIENT_FIFO_NAME, my_data.client_pid);
if (mkfifo(client_fifo, 0777) == -1) {
fprintf(stderr, "Sorry, can't make %s\n", client_fifo);
exit(EXIT_FAILURE);
}
6. В каждом из пяти проходов цикла клиентские данные отправляются на сервер. Далее клиентский FIFO открывается (в режиме "только для чтения" с блокировкой) и данные считываются обратно. В конце серверный FIFO закрывается, а клиентский FIFO удаляется из файловой системы.
for (times_to_send = 0; times_to_send < 5; times_to_send++) {