.png)
Моя цель — создать простой эхо-сервер, используя nc
и один fifo
. Я не ищу лучший способ сделать это, я просто пытаюсь понять семантику следующих команд (когда происходит fork, почему, что он меняет, почему команды ведут себя по-разному...).
Я использую Bash, поэтому не уверен, что все команды будут работать с POSIX sh
или zsh
, ksh
, ...
Вот четыре команды, которые я упоминаю в заголовке (предполагая, что я это уже сделал mkfifo fifo
):
cat fifo | nc -l localhost 8888 > fifo
exec 3<> fifo && nc -l localhost 8888 <&3 >&3 && exec 3>&-
nc -l localhost 8888 <(cat fifo) > fifo
nc -l localhost 8888 < fifo > fifo
Теперь я ожидаю, что 4 команды будут делать одно и то же, по крайней мере, две последние команды будут делать одно и то же.
- Первая команда ведет себя так, как и ожидалось: простой эхо-сервер, который отключается, когда клиент закрывает соединение.
- Ведет себя как 1.
- Я могу подключиться к серверу, отправить данные, но я никогда ничего не получаю обратно. Когда я закрываю клиентское соединение, сервер выключается.
- Невозможно подключиться к серверу, сервер слушает вечно.
решение1
Ключевым моментом здесь является то, что открытие FIFO является блокирующей операцией. open
Единственный возврат происходит, когда оба конца соединены, т. е. когда fifo открыт и для чтения, и для записи.
Normally, opening the FIFO blocks until the other end is opened also.
В первом случае оболочка разветвляется для выполнения конвейера, поэтому открытие fifo для чтения ( cat fifo
) и открытие fifo для записи ( > fifo
) происходят в отдельных процессах, то есть независимо.
Во втором случае открытие для чтения и открытие для записи ( 3<>fifo
) происходят за один шаг.
В 3-м случае <(cat fifo)
расширяется до имени файла, например /dev/fd/42
. Так что это похоже на то, что вы запускаете nc -l localhost 8888 /dev/fd/42 > fifo
. Вам нужен дополнительный <
, чтобы это было эквивалентно, например nc -l localhost 8888 < <(cat fifo) > fifo
.
В 4-м случае оболочка пытается открыть fifo для чтения ( < fifo
) и открыть его для записи ( > fifo
) как часть одного и того же процесса. Оболочка делает это по одному, слева направо. Поэтому она пытается открыть fifo
для чтения и блокируется навсегда, ожидая, пока что-то откроется fifo
для записи. Я думаю, вы обнаружите, что в этом случае nc
даже не начиналось, и порт никогда не открывался для прослушивания.