Использование именованных каналов ввода / вывода для соединения TCP


15

Некоторое время я возился с тем, чтобы заставить это работать, поэтому я подозреваю, что какое-то фундаментальное недоразумение о том, как работают каналы, является основной причиной моих проблем.

Моя цель - инициировать TCP-соединение с некоторым удаленным хостом через netcatи иметь два именованных канала в файловой системе: один, из которого процессы могут читать, чтобы получить входящие данные, и другой, который процессы могут записывать в этот файл, который служит в качестве исходящих данных. В настоящее время я использую следующую конструкцию:

mkfifo in
mkfifo out
cat out | netcat foo.bar.org 4000 > in &

Отсюда я хотел бы разрешить другим процессам читать и записывать в / из этого открытого TCP-соединения. Должно ли это «просто работать», или есть причина, почему такая конструкция не может работать?

Что , кажется , произойдут в настоящее время является то , что я могу читать outбез проблем, но когда я пишу inя получаю выход упоминая сломанную трубу и все последующие связи появляются мертвыми. Мысли?

(Связанный: я первоначально использовал:

netcat foo.bar.org 4000 < out > in &

но нашел его, чтобы заблокировать ожидание ввода. Мне тоже интересно об этом, но, вероятно, это лучше рассмотреть в отдельном вопросе.)

Ответы:


6
cat out | netcat foo.bar.org 4000 > in &

Я думаю, что проблема в том, что catвыйдет, как только получит сообщение EOFиз outтрубы. А когда catвыходит, остальная часть конвейера (включая netcat) также завершается.

Попробуйте что-то вроде этого:

while true; do cat out; done | netcat foo.bar.org 4000 > in &

Таким образом, catперезапуск происходит так часто, как это необходимо, и любые EOFs, появляющиеся в outтрубе, эффективно обрабатываются.


Я попробовал это, но все еще получаю write(stdout): Broken pipeпосле (или вскоре после) записи в outтрубу.
Ноффл

2

Я тоже столкнулся с этой проблемой. Основная проблема есть netcat. Это отличный инструмент, но он закрывает соединение, когда один из его подключенных дескрипторов входных или выходных файлов закрыт. Он ничего не делает, когда сервер не слушает, и закрывается, когда другой узел закрыт. Пока вы правильно настроите сервер и сохраните дескрипторы файлов открытыми, он будет работать. Например, я протестировал следующий сценарий, и он работал очень хорошо: в настройках терминала эхо-сервер (я настроил его, как показано ниже):

mkfifo loopFF
netcat -t -l -p 4000 <loopFF | tee loopFF

Теперь в другом терминале настройте ваше соединение fifo с вашим сервером:

mkfifo in
mkfifo out
netcat 127.0.0.1 4000 <out >in &

распечатывать все, что сервер отправляет вам (и продолжать работать, если вы используете infifo в приложении, которое закрывает один конец по завершению, netcatзакрывает соединение)

cat in &

и в том же терминале:

cat > out

теперь все, что вы печатаете, будет напечатано снова (после нажатия Enter). Закрытие этой команды также закроет соединение.


Я вижу, что это не тот случай, когда я сам пробую это сделать, но почему бы netcat -t -l -p 4000 < loopFF | tee loopFFне вызвать бесконечный цикл обратной связи с самим собой?
noffle

@noffle, потому что, как я уже сказал, netcatзакрывается всякий раз, когда закрывается одно из его сетевых подключений. Если вы закроете клиент (который отправит строку и получит ту же строку), netcatсервер также будет закрыт. В этом случае я написал для себя серверный код, который разветвляется для обработки нескольких клиентов и повторного подключения клиентов.
Саидн

2

Анализ Стивена Понедельника выглядит хорошо для меня: catвозвращается после вашей первой записи, outпотому что fifo есть empty. Чтобы избежать этого, решение состоит в том, чтобы сохранить процесс с открытым fifo в режиме записи, 1-й catв приведенном ниже примере:

mkfifo in
mkfifo out
cat > out &
echo $! > out-pid
cat out | netcat foo.bar.org 4000 > in &

(Файл out-pid - это способ остановить все это kill -9 $(cat out-pid).)

Еще один пример здесь .

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.