Utilisation de canaux nommés d'entrée / sortie pour une connexion TCP

15

Cela fait un moment que je cherche à faire en sorte que cela fonctionne, donc je soupçonne une sorte de malentendu fondamental sur le fonctionnement des tuyaux est la cause première de mes problèmes.

Mon objectif est d'initier une connexion TCP à un hôte distant via netcatet d'avoir deux canaux nommés sur le système de fichiers: l'un à partir duquel les processus peuvent lire pour obtenir les données entrantes, et l'autre à partir duquel les processus peuvent écrire pour servir de données sortantes. J'utilise actuellement la construction suivante:

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

À partir d'ici, je voudrais autoriser d'autres processus à lire et à écrire vers / depuis cette connexion TCP ouverte. Est-ce que cela "devrait juste fonctionner", ou y a-t-il une raison pour laquelle une construction comme celle-ci ne peut pas fonctionner?

Ce qui semble se produire actuellement, c'est que je peux lire outsans problème, mais lorsque j'écris sur, inj'obtiens une sortie mentionnant un tuyau cassé et toutes les communications ultérieures semblent être mortes. Pensées?

(Connexes: j'ai utilisé à l'origine:

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

mais l'a trouvé pour bloquer l'attente de l'entrée. Je suis également curieux à ce sujet, mais il vaut probablement mieux en parler dans une question distincte.)

noffle
la source

Réponses:

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

Je pense que le problème est que cela catsortira dès qu'il recevra un EOFdu outtuyau. Et à la catsortie, le reste du pipeline (y compris netcat) est également arrêté.

Essayez plutôt quelque chose comme ceci:

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

Ainsi, catest redémarré aussi souvent que nécessaire et tous les EOFs apparaissant dans le outtuyau sont traités efficacement.

Steven Monday
la source
J'ai essayé cela, mais je reçois toujours write(stdout): Broken pipeaprès (ou peu de temps après) l'écriture sur le outtuyau.
noffle
2

J'avais aussi fait face à ce problème. Le principal problème est netcat. C'est un excellent outil, mais il ferme la connexion lorsque l'un de ses descripteurs de fichiers d'entrée ou de sortie connectés est fermé. Il ne fait rien lorsque le serveur n'écoute pas et se ferme lorsque l'autre homologue est fermé. Tant que vous configurez le serveur correctement et que vos descripteurs de fichiers restent ouverts, cela fonctionnera. Par exemple, j'ai testé le scénario suivant et cela a très bien fonctionné: dans une configuration de terminal, un serveur d'écho (je l'ai configuré comme ci-dessous):

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

maintenant, dans un autre terminal, configurez votre connexion fifo à votre serveur:

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

imprimer tout ce que le serveur vous envoie (et le faire fonctionner, si vous utilisez infifo dans une application qui ferme une extrémité à sa fin, netcatferme la connexion)

cat in &

et dans le même terminal:

cat > out

tout ce que vous tapez sera à nouveau imprimé (après avoir appuyé sur Entrée). La fermeture de cette commande fermera également la connexion.

saeedn
la source
Je peux voir que ce n'est pas le cas lorsque je l'essaye moi-même, mais pourquoi ne netcat -t -l -p 4000 < loopFF | tee loopFFprovoque- t-il pas une boucle de rétroaction infinie avec lui-même?
noffle
@noffle car, comme je l'ai dit, netcatse fermera chaque fois que l'une de ses connexions réseau se fermera. Si vous fermez le client (qui envoie une chaîne et reçoit la même chaîne), le netcatserveur sera également fermé. J'ai écrit un code de serveur pour moi dans ce cas qui se fourche pour gérer plusieurs clients et se reconnecter de clients.
saeedn
2

L'analyse de Steven Monday me semble bonne: catrevient après votre 1ère écriture outcar la fifo l'est empty. Pour éviter cela, la solution est de garder un processus avec le fifo ouvert en mode écriture, le 1er catdans l'exemple ci-dessous:

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

(Le fichier out-pid est le moyen d'arrêter le tout:. kill -9 $(cat out-pid))

Un autre exemple ici .

jfg956
la source