¿Comportamiento de Netcat / Socat con tuberías y UDP?

16

Supongo que esto está cerca de Linux - Netcat deja de escuchar el tráfico UDP - Super Usuario , pero pensé que sería mejor preguntar de todos modos

En cuanto a las versiones de netcat , estoy usando Ubuntu 11.04 y el valor predeterminado netcat, que supongo es el siguiente openbsd:

$ 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]]

 

Esto es lo que me parece extraño: el primer caso funciona como se esperaba: abro un servidor UDP en una terminal:

$ sudo nc -ul 5000

... y en otra terminal inicio una nueva conexión de cliente UDP, y escribo hellotres veces, presionando ENTER después de cada una:

$ nc -u 127.0.0.1 5000
hello
hello
hello
^C

... y volviendo a la terminal del servidor, se ha impreso hellotres veces, como se esperaba:

$ sudo nc -ul 5000 
hello
hello
hello
^C

 

Hasta ahora todo bien, todo funciona como se esperaba. Sin embargo, supongamos que intento lo mismo al ingresar datos al cliente; establezca primero un servidor UDP en una terminal:

$ sudo nc -ul 5000

... y en otro, canalizar algunos datos nccomo cliente UDP:

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

... después del comando del cliente, el shell se congela como si esperara una entrada, así que allí escribo helloy ENTRO dos veces más; pero el servidor ha registrado solo el primero hello(que se canalizó a través de echo). Por otra parte, aunque se pulse Ctrl-C, y tratar de repetir el cliente echo hello | nc -u 127.0.0.1 5000de comando, el servidor sigue siendo el haber reportado sólo la primera hello:

$ sudo nc -ul 57130 
hello
^C

... y solo después de detener el servidor con Ctrl-C y reiniciarlo nuevamente, se puede repetir el echo hello | nc -u 127.0.0.1 5000comando del cliente y observar que funciona.

 

¿Es así como ncse supone que debe comportarse? Esperaría que al menos las llamadas repetidas echo hello | nc -u 127.0.0.1 5000se registraran sin tener que reiniciar el servidor. ¿O tal vez hay un interruptor de línea de comandos especial para ese tipo de comportamiento?

EDITAR: Encontré esta bonita presentación en PDF: socat: manejo de todo tipo de zócalos , que contiene las siguientes notas netcatvs socat:

netcat - Limitaciones
● one-shot only (termina después del cierre del socket)
...
Ejemplos 1: reemplazo de netcat
...
● Cliente UDP con puerto de origen:
nc -u -p 500 1.2.3.4 500
socat - udp: 1.2.3.4: 500, sp = 500
● Servidor TCP:
nc -l -p 8080
socat - tcp-l: 8080, reuseaddr
...

... sin embargo, estoy obteniendo el mismo comportamiento que el anterior, si reemplazo el comando del servidor con " socat - udp4-listen:5000,reuseaddr" - y la línea del cliente con " socat - udp:127.0.0.1:5000" ... Con la entrada canalizada, " echo hello | socat - udp:127.0.0.1:5000", la única diferencia es que aquí el comando al menos existe después de que hellose haya enviado la palabra ; sin embargo, nuevamente, las ejecuciones consecutivas de este comando no causarán ninguna recepción en el servidor, hasta que se reinicie el servidor.

sdaau
fuente

Respuestas:

23

Ok, creo que al menos obtuve algo socat, es decir, la opción forkdebe agregarse a la línea del servidor:

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

... y luego, en otra terminal, podemos llamar la echotubería a socatla línea del cliente varias veces en la línea de comando, ya que saldrá inmediatamente ( bueno, después de medio segundo :) ):

$ 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

... y volviendo a la primera terminal, podemos ver que el servidor ha mostrado con éxito las tres hellos:

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

 

Tenga en cuenta que incluso con un servidor fork-ed socat, la línea echo "hello" | nc -u 127.0.0.1 5000seguirá "bloqueándose" como si esperara la entrada del usuario; sin embargo, ahora después de Ctrl-C y volver a ejecutar el comando, es decir

$ 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

... el servidor fork-ed socatmostrará tres hellos sin la necesidad de reiniciar.

 

Aparentemente, este openBSD netcatno tiene una forkopción, pero no estoy seguro si tiene una que le corresponda.

De todos modos, espero que esto ayude a alguien,
¡salud!

sdaau
fuente
4

Su netcat solo está leyendo la salida de stdout de echo cuando usa pipe, ya no está "conectado" al teclado. Para obtener la respuesta que espera, puede agregar sus tres "hola" a un archivo y ejecutar

cat [myfile] | nc -u 127.0.0.1 5000
OldWolf
fuente
Hola @OldWolf: muchas gracias por tu respuesta. Intenté su sugerencia (también de una manera algo más complicada, " cat $(echo -e "hello\nhello\nhello\n" > tmpf; echo tmpf) | nc -u 127.0.0.1 5000"), sin embargo, aunque veo tres hellos, lo que me desconcierta todavía está presente: ese comando también se "bloqueará", como si esperara la entrada escrita de usuario, y después de Ctrl-C y volver a ejecutarlo, el servidor no verá ningún dato hasta que se reinicie. Eso es lo que me gustaría saber mejor: ¡salud!
sdaau
2
nc está esperando un EOF que, en este caso, no aparece hasta que envía la señal de salida al programa.
OldWolf
Ahh, ya veo. ¡Muchas gracias por esa explicación, @OldWolf! Aparentemente socatpuede solucionar eso con la forkopción ... Gracias de nuevo, ¡salud!
sdaau
3

Si haces una secuencia de nc de escucha, mostrará que netcat está esperando la conexión, y una vez que la obtenga, se conectará a ese host y puerto, ignorando a todos los demás. Debe agregar '-k' para continuar y '-w 0' para agotar el tiempo de espera de cada conexión después de 0 segundos. Socat es una mejor opción, creo.

pdragon
fuente