Comportement de Netcat / socat avec la tuyauterie et UDP?

16

Je suppose que c'est proche de Linux - Netcat arrête d'écouter le trafic UDP - Super User , mais je pensais que je ferais mieux de demander quand même

En ce qui concerne les versions de netcat, j'utilise Ubuntu 11.04 et la valeur par défaut netcat, ce qui, je suppose, est celui- openbsdci:

$ nc
This is nc from the netcat-openbsd package. An alternative nc is available
in the netcat-traditional package.
usage: nc [-46DdhklnrStUuvzC] [-i interval] [-P proxy_username] [-p source_port]
      [-s source_ip_address] [-T ToS] [-w timeout] [-X proxy_protocol]
      [-x proxy_address[:port]] [hostname] [port[s]]

 

Voici ce que je trouve étrange: le premier cas fonctionne comme prévu - j'ouvre un serveur UDP dans un terminal:

$ sudo nc -ul 5000

... et dans un autre terminal, j'initie une nouvelle connexion client UDP - et je tape hellotrois fois, en appuyant sur ENTRÉE après chaque:

$ nc -u 127.0.0.1 5000
hello
hello
hello
^C

... et revenant au terminal serveur, il a imprimé hellotrois fois, comme prévu:

$ sudo nc -ul 5000 
hello
hello
hello
^C

 

Jusqu'ici tout va bien, tout fonctionne comme prévu. Cependant, disons que j'essaie maintenant la même chose en canalisant l'entrée dans le client; établissez donc d'abord un serveur UDP dans un terminal:

$ sudo nc -ul 5000

... et dans un autre, canalisez certaines données en nctant que client UDP:

$ echo hello | nc -u 127.0.0.1 5000
hello
hello
^C

... après la commande client, le shell se fige comme s'il attendait une entrée - alors là, je tape helloet ENTRER deux fois de plus; mais le serveur n'a enregistré que le premier hello(qui a été acheminé via echo). De plus, même si vous appuyez sur Ctrl-C, et essayer de répéter le client echo hello | nc -u 127.0.0.1 5000commande, le serveur toujours rester d'avoir rapporté que la première hello:

$ sudo nc -ul 57130 
hello
^C

... et seulement après avoir arrêté le serveur avec Ctrl-C et l'avoir redémarré, on peut répéter la echo hello | nc -u 127.0.0.1 5000commande client et l'observer fonctionner.

 

Est-ce ainsi que le nccomportement est censé se comporter? Je m'attendrais à ce qu'au moins des appels répétés echo hello | nc -u 127.0.0.1 5000soient enregistrés - sans avoir à redémarrer le serveur? Ou peut-être existe-t-il un commutateur de ligne de commande spécial pour ce type de comportement?

EDIT: J'ai trouvé cette belle présentation PDF: socat - Handling all Sortes of Sockets , qui contient les notes netcatvs suivantes socat:

netcat - Limitations
● one-shot seulement (se termine après la fermeture du socket)
...
Exemples 1: remplacement netcat
...
● Client UDP avec port source:
nc -u -p 500 1.2.3.4 500
socat - udp: 1.2.3.4: 500, sp = 500
● Serveur TCP:
nc -l -p 8080
socat - tcp-l: 8080, reuseaddr
...

... cependant, j'obtiens à peu près le même comportement que ci-dessus, si je remplace la commande serveur par " socat - udp4-listen:5000,reuseaddr" - et la ligne client par " socat - udp:127.0.0.1:5000" ... Avec l'entrée canalisée, " echo hello | socat - udp:127.0.0.1:5000", la seule différence est que ici, la commande existe au moins après l' helloenvoi du mot - cependant, encore une fois, des exécutions consécutives de cette commande n'entraîneront aucune réception sur le serveur, jusqu'à ce que le serveur soit redémarré.

sdaau
la source

Réponses:

23

Ok, je pense qu'au moins j'ai quelque chose avec socat- à savoir, l'option forkdoit être ajoutée à la ligne de serveur:

$ socat - udp4-listen:5000,reuseaddr,fork

... puis, dans un autre terminal, nous pouvons appeler la echotuyauterie dans la socatligne client plusieurs fois sur la ligne de commande, car elle se fermera immédiatement ( enfin, après une demi-seconde :) ):

$ echo "hello" | socat - udp-sendto:127.0.0.1:5000
$ echo "hello" | socat - udp-sendto:127.0.0.1:5000
$ echo "hello" | socat - udp-sendto:127.0.0.1:5000

... et revenons au premier terminal, nous pouvons voir que le serveur a réussi à afficher les trois hellos:

$ socat - udp4-listen:5000,reuseaddr,fork
hello
hello
hello
^C

 

Notez que même avec un serveur fork-ed socat, la ligne echo "hello" | nc -u 127.0.0.1 5000«se verrouillera» comme si elle attendait la saisie de l'utilisateur; cependant, maintenant après Ctrl-C et relancer la commande, c.-à-d.

$ echo "hello" | nc -u 127.0.0.1 5000
^C
$ echo "hello" | nc -u 127.0.0.1 5000
^C
$ echo "hello" | nc -u 127.0.0.1 5000
^C

... le serveur fork-ed socataffichera trois hellos sans avoir besoin d'être redémarré ..

 

Apparemment, cet openBSD netcatn'a pas d' forkoption - mais je ne sais pas s'il en a une qui lui correspond.

Quoi qu'il en soit, j'espère que cela aide quelqu'un,
Cheers!

sdaau
la source
4

Votre netcat ne lit la sortie de la sortie standard d'écho que lorsque vous utilisez un tuyau, il n'est plus "connecté" au clavier. Pour obtenir la réponse que vous attendez, vous pouvez ajouter vos trois "bonjour" à un fichier une exécution

cat [myfile] | nc -u 127.0.0.1 5000
OldWolf
la source
Salut @OldWolf - merci beaucoup pour votre réponse! J'ai essayé votre suggestion (également d'une manière un peu plus compliquée, " cat $(echo -e "hello\nhello\nhello\n" > tmpf; echo tmpf) | nc -u 127.0.0.1 5000"), cependant, alors que je vois trois hellos, ce qui me laisse perplexe est toujours présent: cette commande va également trier "verrouiller", comme si vous attendiez une entrée tapée de utilisateur, et après Ctrl-C et le réexécutant, le serveur ne verra aucune donnée jusqu'à ce qu'il soit redémarré!? C'est ce que j'aimerais mieux savoir - cheers!
sdaau
2
nc attend un EOF que, dans ce cas, il n'obtient pas tant que vous n'avez pas envoyé le signal de sortie au programme.
OldWolf
Ahh, je vois - merci beaucoup pour cette explication, @OldWolf! Apparemment, cela socatpeut fonctionner avec l' forkoption ... Merci encore, bravo!
sdaau
3

Si vous effectuez une séquence d'écoute nc, cela montrera que netcat attend la connexion, et une fois qu'il l'obtiendra, se connectera à cet hôte et à ce port, ignorant tous les autres. Vous devez ajouter «-k» pour continuer et «-w 0» pour expirer chaque connexion après 0 seconde. Socat est un meilleur choix, je pense.

pdragon
la source