Використання названих труб для з'єднання 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перезапускається стільки разів, скільки потрібно, і будь-які види, EOFщо з’являються в outтрубі, ефективно обробляються.


Я спробував це, але все одно отримую write(stdout): Broken pipeпісля (або незабаром після) написання на outтрубу.
noffle

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сервер також буде закритий. Я написав код сервера для себе в цьому випадку, який примушує себе обробляти декілька клієнтів і знову підключатися до клієнтів.
saeedn

2

Аналіз Стівена Понеділка мені добре виглядає: catповертається після Вашого першого запису, outтому що це фіфо empty. Щоб уникнути цього, рішення полягає в тому, щоб тримати процес з відкритою фіфою в режимі запису, 1-й catу наведеному нижче прикладі:

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

(Вихідний файл - це спосіб зупинити все:. kill -9 $(cat out-pid))

Ще один приклад тут .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.