Verwenden von In / Out-Named Pipes für eine TCP-Verbindung

15

Ich habe schon eine Weile damit rumgespielt, dass das funktioniert, und ich vermute, dass ein grundlegendes Missverständnis darüber, wie Pipes funktionieren, die Ursache für meine Probleme ist.

Mein Ziel ist es, eine TCP-Verbindung zu einem Remote-Host über zu initiieren netcatund zwei Named Pipes im Dateisystem zu haben: Eine, von der Prozesse lesen können, um eingehende Daten abzurufen, und eine, auf die Prozesse schreiben können, dienen als ausgehende Daten. Ich benutze derzeit die folgende Konstruktion:

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

Von hier aus möchte ich anderen Prozessen erlauben, auf diese offene TCP-Verbindung zu lesen und zu schreiben. Sollte dies "nur funktionieren", oder gibt es einen Grund, warum ein Konstrukt wie dieses nicht funktionieren kann?

Momentan scheint es so zu sein, dass ich outohne Probleme lesen kann , aber wenn ich schreibe, inerhalte ich eine Ausgabe, in der eine kaputte Pipe erwähnt wird, und die gesamte nachfolgende Kommunikation scheint tot zu sein. Gedanken?

(Verwandte: Ich habe ursprünglich verwendet:

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

fand es aber zu blockieren warten auf eingabe. Ich bin auch neugierig, aber es wird wahrscheinlich besser in einer separaten Frage angesprochen.)

Noffle
quelle

Antworten:

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

Ich denke, das Problem ist, dass es beendet catwird, sobald es eine EOFvon der outPipe erhält . Beim Beenden wird auch catder Rest der Pipeline (einschließlich netcat) beendet.

Versuchen Sie stattdessen Folgendes:

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

Somit catwird so oft wie nötig neu gestartet, und alle EOFin der outPipe auftretenden S werden effektiv behandelt.

Steven Montag
quelle
Ich habe es versucht, erhalte aber immer noch write(stdout): Broken pipenach (oder kurz danach) Schreiben an die outPipe.
Noffle
2

Ich hatte mich auch mit diesem Problem konfrontiert. Das Hauptproblem ist netcat. Es ist ein großartiges Tool, aber es schließt die Verbindung, wenn einer der verbundenen Eingabe- oder Ausgabedateideskriptoren geschlossen wird. Es macht nichts, wenn der Server nicht lauscht und es wird beendet, wenn der andere Peer geschlossen wird. Solange Sie den Server korrekt einrichten und Ihre Dateideskriptoren geöffnet lassen, funktioniert es. Ich habe zum Beispiel das folgende Szenario getestet und es hat sehr gut funktioniert: In einem Terminal-Setup einen Echoserver (ich habe es wie folgt eingerichtet):

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

Jetzt in einem anderen Terminal einrichten Sie Ihre FIFO-Verbindung zu Ihrem Server:

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

Was auch immer der Server an Sie sendet, drucken Sie aus (und lassen Sie es laufen, wenn Sie infifo in einer Anwendung verwenden, die bei Beendigung ein Ende netcatschließt, wird die Verbindung geschlossen).

cat in &

und im selben Terminal:

cat > out

Jetzt wird alles, was Sie eingeben, erneut gedruckt (nachdem Sie die Eingabetaste gedrückt haben). Durch Schließen dieses Befehls wird auch die Verbindung geschlossen.

saeedn
quelle
Ich kann sehen, dass es nicht der Fall ist, wenn ich es selbst ausprobiere, aber warum netcat -t -l -p 4000 < loopFF | tee loopFFverursacht es keine unendliche Rückkopplungsschleife mit sich selbst?
Noffle
@noffle weil, wie gesagt, immer netcatdann geschlossen wird, wenn eine seiner Netzwerkverbindungen geschlossen wird. Wenn Sie den Client schließen (der eine Zeichenfolge sendet und dieselbe Zeichenfolge empfängt), wird auch der netcatServer geschlossen. In diesem Fall habe ich einen Server-Code für mich geschrieben, der sich dazu auffordert, mehrere Clients zu verwalten und die Verbindung der Clients wiederherzustellen.
Saeedn
2

Die Analyse von Steven Monday sieht für mich gut aus: Kommt catnach Deinem 1. Schreiben wieder an, outweil der Fifo ist empty. Um dies zu vermeiden, ist die Lösung, einen Prozess mit geöffnetem FIFO im Schreibmodus zu belassen, der erste catim folgenden Beispiel:

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

(Die Out-PID-Datei ist der Weg, um das Ganze zu stoppen:. kill -9 $(cat out-pid))

Ein weiteres Beispiel hier .

jfg956
quelle