Структура
Для создания именованных каналов будем использовать функцию, :
#include <sys/stat.h> int mkfifo(const char *pathname, mode_t mode);
Функция создает специальный FIFO файл с именем pathname, а параметр mode задает права доступа к файлу.
Примечание: используется в сочетании с текущим значением /code>umask</code> следующим образом: (). Результатом этой операции и будет новое значение umask для создаваемого нами файла. По этой причине мы используем 0777 (), чтобы не затирать ни один бит текущей маски.
Как только файл создан, любой процесс может открыть этот файл для чтения или записи также, как открывает обычный файл. Однако, для корректного использования файла, необходимо открыть его одновременно двумя процессами/потоками, одним для получение данных (чтение файла), другим на передачу (запись в файл).
В случае успешного создания FIFO файла, mkfifo() возвращает 0 (нуль). В случае каких либо ошибок, функция возвращает -1 и выставляет код ошибки в переменную errno.
Типичные ошибки, которые могут возникнуть во время создания канала:
- — нет прав на запуск (execute) в одной из директорий в пути
- — файл pathname уже существует, даже если файл — символическая ссылка
- — не существует какой-либо директории, упомянутой в pathname, либо является битой ссылкой
- — нет места для создания нового файла
- — одна из директорий, упомянутых в pathname, на самом деле не является таковой
- — попытка создать FIFO файл на файловой системе «только-на-чтение»
Чтение и запись в созданный файл производится с помощью функций read() и write().
Пример:
#include <sys/stat.h> #include <fcntl.h> #include <string.h> #include <stdio.h> #define NAMEDPIPE_NAME "/tmp/my_named_pipe" #define BUFSIZE 50 int main (int argc, char ** argv) { int fd, len; char bufBUFSIZE]; if ( mkfifo(NAMEDPIPE_NAME, 0777) ) { perror("mkfifo"); return 1; } printf("%s is created\n", NAMEDPIPE_NAME); if ( (fd = open(NAMEDPIPE_NAME, O_RDONLY)) <= ) { perror("open"); return 1; } printf("%s is opened\n", NAMEDPIPE_NAME); do { memset(buf, '\0', BUFSIZE); if ( (len = read(fd, buf, BUFSIZE-1)) <= ) { perror("read"); close(fd); remove(NAMEDPIPE_NAME); return ; } printf("Incomming message (%d): %s\n", len, buf); } while ( 1 ); }
Мы открываем файл только для чтения (O_RDONLY). И могли бы использовать O_NONBLOCK модификатор, предназначенный специально для FIFO файлов, чтобы не ждать когда с другой стороны файл откроют для записи. Но в приведенном коде такой способ неудобен.
Компилируем программу, затем запускаем ее:
$ gcc -o mkfifo mkfifo.c $ ./mkfifo
В соседнем терминальном окне выполняем:
$ echo 'Hello, my named pipe!' > /tmp/my_named_pipe
В результате мы увидим следующий вывод от программы:
$ ./mkfifo /tmp/my_named_pipe is created /tmp/my_named_pipe is opened Incomming message (22): Hello, my named pipe! read: Success
Вопросы безопасности
В этом разделе описывается, каким образом злоумышленник может использовать компонент или его конфигурацию, как реализовать меры противодействия, а также рассматриваются возможные отрицательные последствия их реализации.
Уязвимость
Вы можете ограничить доступ к таким каналам, как COMNAP и LOCATOR, чтобы предотвратить несанкционированный доступ к сети. В следующем списке описаны доступные с именем трубы и их назначение. Эти трубы были предоставлены анонимный доступ в более ранних версиях Windows и некоторые устаревшие приложения могут по-прежнему использовать их.
Именоваемая труба | Описание |
---|---|
COMNAP | SNABase с именем pipe. Systems network Architecture (SNA) — это коллекция сетевых протоколов, изначально разработанных для компьютеров ibm mainframe. |
COMNODE | SNA Server с именем pipe. |
SQL\QUERY | По умолчанию называется труба для SQL Server. |
SPOOLSS | Названа труба для службы Print Spooler. |
EPMAPPER | Картограф конечных точечной точки с именем pipe. |
LOCATOR | Служба локатора удаленной процедуры с именем pipe. |
TrlWks | Распределенный клиент отслеживания ссылок с именем pipe. |
TrkSvr | Распределенный сервер отслеживания ссылок с именем pipe. |
Противодействие
Настройка сетевого доступа: Именные трубы, к которые можно получить анонимный доступ, устанавливая значение null (включить параметр, но не указывать именные трубы в текстовом окне).
Возможное влияние
Эта конфигурация отключает доступ null-session к названным трубам, а приложения, которые полагаются на эту функцию или неавентированный доступ к названным трубам, больше не функционируют. Это может нарушить доверие между доменами Windows Server 2003 в среде смешанного режима.
Неименованные каналы
Неименованный канал создается вызовом pipe, который заносит в массив int два дескриптора открытых файлов. fd – открыт на чтение, fd – на запись (вспомните STDIN == 0, STDOUT == 1). Канал уничтожается, когда будут закрыты все файловые дескрипторы ссылающиеся на него.
В рамках одного процесса pipe смысла не имеет, передать информацию о нем в произвольный процесс нельзя (имени нет, а номера файловых дескрипторов в каждом процессе свои). Единственный способ использовать pipe – унаследовать дескрипторы при вызове (и последующем ). После вызова fork канал окажется открытым на чтение и запись в родительском и дочернем процессе. Т.е. теперь на него будут ссылаться 4 дескриптора. Теперь надо определиться с направлением передачи данных – если надо передавать данные от родителя к потомку, то родитель закрывает дескриптор на чтение, а потомок — дескриптор на запись.
Оставлять оба дескриптора незакрытыми плохо по двум причинам:
-
Родитель после записи не может узнать считал ли дочерний процесс данные, а если считал то сколько. Соответственно, если родитель попробует читать из pipe, то, вполне вероятно, он считает часть собственных данных, которые станут недоступными для потомка.
-
Если один из процессов завершился или закрыл свои дескрипторы, то второй этого не заметит, так как pipe на его стороне по-прежнему открыт на чтение и на запись.
Если надо организовать двунаправленную передачу данных, то можно создать два pipe.
Различайте по типу общения
- Система с общей памятью 1. Метод связи на основе общей структуры данных (подходит только для передачи относительно небольшого объема данных, низкая эффективность связи, принадлежность к низкоуровневой связи) 2. Метод связи на основе общей области хранения
- Система трубопроводной связи Канал означает общий файл (файл канала), используемый для соединения процесса чтения и процесса записи для связи между ними. Механизм конвейера должен обеспечивать следующие возможности координации 1. Взаимоисключающие, то есть когда процесс выполняет операции чтения / записи в канале, другие процессы должны ждать 2. Синхронизация: когда процесс записывает определенный объем данных, он переходит в спящий режим и ждет, пока процесс чтения не заберет данные, а затем просыпается. Процесс чтения аналогичен 3. Определите, существует ли другая сторона
- Система обмена сообщениями 1. Метод прямой связи Процесс отправки использует примитивы отправки, предоставляемые ОС, для прямой отправки сообщения целевому процессу. 2. Косвенный метод связи Процессы отправки и получения отправляют и получают сообщения через общие объекты (почтовые ящики)
- Клиент-серверная система 1. Структура данных идентификации сокет-связи является основным компонентом взаимодействия процессов и сетевых коммуникаций. На основе файлов (когда процесс связи осуществляется на одном сервере), принцип аналогичен конвейеру. Сетевая (асимметричная связь, отправитель должен указать имя получателя. Процессы обеих сторон выполняются в разных средах хоста и им назначается пара сокетов, один принадлежит отправителю Процесс, один принадлежит принимающему процессу) 2. Удаленный вызов процедуры и удаленный вызов метода.
Два, FIFO
FIFO, Также называется именованным каналом, который представляет собой тип файла
1. Особенности:
3. FIFO (первый вход — первый выход) всегда следует принципу «первым пришел — первым вышел», то есть первые входящие данные будут считаны первыми.
2. Прототип:
Примечание. Обе функции могут создавать файл FIFO, который фактически существует в файловой системе. Путь к параметру в функции mknod — это полный путь для создания именованного канала; mod — режим создания именованного канала, который относится к его полномочиям доступа; dev — значение устройства, и значение зависит от типа создания файла. Он используется только для создания файла устройства. Будет использовано. Чтобы
Возвращаемое значение: обе функции возвращают 0 в случае успеха и -1 в случае неудачи.
После создания именованного канала его можно использовать.Метод использования такой же, как и у канала.Разница в том, что именованный канал необходимо открыть с помощью open () перед его использованием. Это связано с тем, что именованные каналы — это файлы устройств, которые хранятся на жестком диске, а каналы — это специальные файлы, хранящиеся в памяти. Но следует отметить, что вызов open () для открытия именованного канала может заблокировать, но если он открыт в режиме чтения-записи (O_RDWR), он не будет блокироваться; при открытии в режиме только для чтения (O_RDONLY) вызовите функцию open () Он будет заблокирован до тех пор, пока данные не станут доступными для чтения; если он открыт в режиме только для записи (O_WRONLY), он также будет заблокирован, зная, что канал открыт в режиме чтения.
3. Примеры
Метод связи FIFO аналогичен использованию файлов для передачи данных в процессе, за исключением того, что файлы типа FIFO также имеют характеристики каналов. Когда данные считываются, данные очищаются в конвейере FIFO одновременно, и «первым пришел — первым вышел». В следующем примере демонстрируется процесс использования FIFO для IPC:
write_fifo.c
read_fifo.c
Вышеупомянутый пример может быть расширен до примера взаимодействия процесса клиент-сервер,Роль аналогична клиенту, вы можете открыть несколько клиентов для отправки информации запроса на сервер,Подобно серверу, он отслеживает конец чтения FIFO в нужное время. Когда есть данные, он считывает и обрабатывает их. Однако ключевой проблемой является то, что каждый клиент должен заранее знать интерфейс FIFO, предоставляемый сервером. На следующем рисунке это показано Договоренности:
Ссылка: 1. http://songlee24.github.io/2015/04/21/linux-IPC/
2.https://blog.csdn.net/qq_33951180/article/details/68959819
Общие методы связи
- Канал: конвейер — это полудуплексный метод связи. Данные могут передаваться только в одном направлении, и его можно использовать только между связанными процессами. Родство процесса обычно относится к отношениям родительско-дочернего процесса.
- Именованный канал FIFO: именованный канал также является полудуплексным методом связи, но он позволяет взаимодействовать между несвязанными процессами.
- Очередь сообщений MessageQueue: очередь сообщений — это связанный список сообщений, хранящийся в ядре и идентифицируемый идентификатором очереди сообщений. Очередь сообщений устраняет недостатки меньшего количества информации о передаче сигнала, конвейер может переносить только неформатированные потоки байтов и ограниченный размер буфера.
- Общая память: Общая память предназначена для отображения раздела памяти, к которому могут получить доступ другие процессы.Эта часть общей памяти создается одним процессом, но несколько процессов могут получить к нему доступ. Совместно используемая память — это самый быстрый метод IPC, специально разработанный с учетом низкой эффективности других методов межпроцессного взаимодействия. Он часто используется в сочетании с другими механизмами связи, такими как семафоры, для достижения синхронизации и связи между процессами.
- Семафор: семафор — это счетчик, который можно использовать для управления доступом к общим ресурсам несколькими процессами. Он часто используется как механизм блокировки для предотвращения доступа других процессов к общим ресурсам, когда процесс обращается к ресурсу. Следовательно, он в основном используется как средство синхронизации между процессами и между разными потоками в одном процессе.
- Socket: Socket — это также механизм межпроцессного взаимодействия, который, в отличие от других механизмов, может использоваться для связи между различными процессами.
- Сигнал (sinal): Сигнал — это более сложный метод связи, используемый для уведомления принимающего процесса о том, что произошло событие.
Правила обмена через канал
Чтение:
- При чтении числа байт, меньшего чем находится в канале, возвращается требуемое число байтов, остаток сохраняется для
последующих чтений. - При чтении числа байт, большего чем находится в канале, возвращается доступное число байт.
- При чтении из пустого канала, открытого каким либо процессом на на запись при сброшенном флаге O_NONBLOCK произойдёт блокировка процесса, а при установленном флаге O_NONBLOCK будет возвращено -1 и установлено значение равное EAGAIN.
- Если канал пуст и ни один процесс не открыл его на запись, то при чтении из канала будет получено 0 байтов — т.е конец файла.
Запись:
- Если процесс пытается записать данные в канал, не открытый ни одним процессом на чтение, то процессу отправляется сигнал SIGPIPE. Если не установлена обработка сигнала, то процесс завершается, в противном случае вызов write() возвращает -1 с установкой ошибки EPIPE.
- Запись числа байт меньше чем PIPE_BUF выполняется атомарно. При записи из нескольких процессов данные не перемешиваются.
- При записи числа байт больше чем PIPE_BUF атомарность операции не гарантируется.
- Если флаг O_NONBLOCK не установлен, то запись может быть заблокирована, но в конце концов будет возвращено значение, указывающее, что все байты записаны.
- Если флаг O_NONBLOCK установлен и записывается меньше чем PIPE_BUF, то возможны два варианта: если есть достаточно свободного места в буфере, то производится атомарная запись, если нет, то возвращается -1, а errno выставляется в EAGAIN.
- Если флаг O_NONBLOCK установлен и записывается больше чем PIPE_BUF то возможны два варианта: если в буфере есть хотя бы один свободный байт, то производится запись доступного числа байт, если нет, то возвращается -1, а errno выставляется в EAGAIN.
Именованный канал в Windows
В Windows дизайн именованных каналов смещён к взаимодействию «клиент-сервер», и они работают во многом как сокеты: помимо обычных операций чтения и записи, именованные каналы в Windows поддерживают явный «пассивный» режим для серверных приложений (для сравнения: сокет домена UNIX). Windows 95 поддерживает клиенты именованных каналов, а системы ветви Windows NT могут служить также и серверами.
К именованному каналу можно обращаться в значительной степени как к файлу. Можно использовать функции Windows API CreateFile, CloseHandle, ReadFile, WriteFile, чтобы открывать и закрывать канал, выполнять чтение и запись. Функции стандартной библиотеки Си, такие, как fopen, fread, fwrite и fclose, тоже можно использовать, в отличие от сокетов Windows (англ.), которые не реализуют использование стандартных файловых операций в сети. Интерфейс командной строки (как в Unix) отсутствует.
Именованные каналы — не существуют постоянно и не могут, в отличие от Unix, быть созданы как специальные файлы в произвольной доступной для записи файловой системе, но имеют временные имена (освобождаемые после закрытия последней ссылки на них), которые выделяются в корне файловой системы именованных каналов (англ. named pipe filesystem, NPFS) и монтируются по специальному пути «\\.\pipe\» (то есть у канала под названием «foo» полное имя будет «\\.\pipe\foo»). Анонимные каналы, использующиеся в конвейерах, — это на самом деле именованные каналы со случайным именем.
Именованные каналы обычно не доступны непосредственно пользователю, но есть существенные исключения. Например, средство виртуализации рабочих станций VMWare может открывать эмулируемый последовательный порт для главной системы как именованный канал, а отладчик уровня ядра kd от Microsoft поддерживает именованные каналы в качестве средства сообщения при отладке (фактически, так как kd обычно требует подключения к целевому компьютеру по последовательному порту, VMware и kd можно соединить вместе для отладки драйверов устройств на одном компьютере). Обе программы требуют от пользователя указания имён канала в виде «\\.\pipe\имя».
Именованные каналы в Windows NT могут наследовать контекст безопасности.