В чем разница пайпа и сокета
Что проверяют
Понимаете ли вы, как устроено межпроцессное взаимодействие на уровне ОС, а не только названия механизмов. Следом обычно просят выбрать механизм под задачу или спрашивают, почему процесс-читатель не получает EOF.
Как отвечать
Общее у них одно: и то и другое в POSIX это файловые дескрипторы, с ними работают read/write, их можно мультиплексировать через poll или epoll. Дальше различия:
- неименованный пайп (
pipe()): однонаправленный байтовый поток, два дескриптора, конец на чтение и конец на запись. Живёт в ядре, доступен только родственным процессам, которые унаследовали дескрипторы черезfork; - именованный пайп (
mkfifo): тот же поток, но с именем в файловой системе, поэтому его открывают любые процессы на той же машине; - сокет: двунаправленный канал с выбором домена и типа.
AF_INET/AF_INET6работают по сети,AF_UNIXлокально. ТипSOCK_STREAMдаёт поток байт,SOCK_DGRAMотдельные сообщения,SOCK_SEQPACKETсообщения поверх установленного соединения.
Хорошо добавить детали, которые показывают практику. У пайпа в Linux буфер по умолчанию 64 КиБ, при заполнении write блокируется, а запись размером до PIPE_BUF (4096 байт) атомарна. Unix-сокеты умеют больше пайпа: передают другому процессу открытые дескрипторы через SCM_RIGHTS и позволяют узнать учётные данные собеседника. socketpair() даёт пару связанных сокетов, по сути двусторонний пайп.
В стандартной библиотеке C++ нет ни пайпов, ни сокетов, поэтому пишут на POSIX API или берут Boost.Asio, где есть и TCP, и local::stream_protocol для Unix-сокетов.
Где спотыкаются
Говорят, что пайп работает только между родителем и потомком. Это верно для неименованного, FIFO открывает любой процесс.
Забывают закрыть неиспользуемые концы после fork. Пока хоть в одном процессе открыт конец на запись, читатель не получит EOF и зависнет на read.
Не обрабатывают SIGPIPE: запись в пайп или сокет, у которого закрыт читатель, по умолчанию убивает процесс. Сигнал игнорируют или шлют данные через send с флагом MSG_NOSIGNAL и проверяют EPIPE.