Comportamento do Netcat / socat com tubulação e UDP?

12

Eu acho que isso é perto de linux - Netcat pára de ouvir o tráfego UDP - Super User , mas achei melhor perguntar de qualquer maneira

Em relação às versões do netcat , estou usando o Ubuntu 11.04 e o padrão netcat em Eu acho que é o openbsd one:

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

Isso é o que eu acho estranho: o primeiro caso funciona como esperado - eu abro um servidor UDP em um terminal:

$ sudo nc -ul 5000

... e em outro terminal eu inicio uma nova conexão de cliente UDP - e eu digito hello três vezes, pressionando ENTER após cada:

$ nc -u 127.0.0.1 5000
hello
hello
hello
^C

... e voltando ao terminal do servidor, ele imprimiu hello três vezes, como esperado:

$ sudo nc -ul 5000 
hello
hello
hello
^C

Até aí tudo bem, tudo funciona como esperado. No entanto, digamos que eu tente agora o mesmo inserindo piping no cliente; então estabeleça primeiro um servidor UDP em um terminal:

$ sudo nc -ul 5000

... e em outro, canalize alguns dados para nc como cliente UDP:

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

... após o comando do cliente, o tipo de shell congela como se estivesse esperando pela entrada - então eu digito hello e ENTER mais duas vezes; mas o servidor registrou apenas o primeiro hello (que foi enviado via echo ). Além disso, mesmo se você pressionar Ctrl-C e tentar repetir o comando client echo hello | nc -u 127.0.0.1 5000 , o servidor ainda permanecerá por ter informado apenas o primeiro hello :

$ sudo nc -ul 57130 
hello
^C

... e somente depois de parar o servidor com Ctrl-C e reiniciá-lo novamente, pode-se repetir o comando cliente echo hello | nc -u 127.0.0.1 5000 e observá-lo funcionando.

Esta é a maneira que o nc deveria estar se comportando? Eu esperaria que pelo menos repetidas chamadas para echo hello | nc -u 127.0.0.1 5000 seriam registradas - sem ter que reiniciar o servidor? Ou talvez haja uma opção de linha de comando especial para esse tipo de comportamento?

EDIT: Eu encontrei esta apresentação em PDF agradável: socat - Manipulando todos os tipos de soquetes , que contém as seguintes notas netcat vs socat :

netcat - Limitations
● one-shot only (terminates after socket close)
...
Examples 1: netcat Replacement
...
● UDP client with source port:
nc -­u ­-p 500 1.2.3.4 500
socat ­- udp:1.2.3.4:500,sp=500
● TCP server:
nc ­-l ­-p 8080
socat ­- tcp­-l:8080,reuseaddr
...

... no entanto, estou praticamente obtendo o mesmo comportamento acima, se eu substituir o comando do servidor por " socat - udp4-listen:5000,reuseaddr " - e a linha do cliente com " socat - udp:127.0.0.1:5000 " ... Com a entrada canalizada , " echo hello | socat - udp:127.0.0.1:5000 ", a única diferença é que aqui o comando existe pelo menos depois que a palavra hello foi enviada - no entanto, novamente, execuções consecutivas desse comando não causarão nenhuma recepção no servidor, até que o servidor seja reiniciado.

    
por sdaau 03.09.2011 / 22:14

3 respostas

17

Ok, acho que pelo menos consegui algo com socat - a opção fork precisa ser anexada à linha do servidor:

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

... e, em outro terminal, podemos chamar echo piping na linha socat client várias vezes na linha de comando, pois ela sairá imediatamente ( bem, após meio 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

... e voltando ao primeiro terminal, podemos ver que o servidor mostrou com sucesso todos os três hello s:

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

Observe que, mesmo com um servidor fork -ed socat , a linha echo "hello" | nc -u 127.0.0.1 5000 continuará 'bloqueada' como se estivesse aguardando a entrada do usuário; no entanto, agora após Ctrl-C e re-executando o comando, ou seja,

$ 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

... o servidor fork -ed socat mostrará três hello s sem a necessidade de ser reiniciado.

Aparentemente, este openBSD netcat não tem uma opção fork - mas não tenho certeza se tem um que corresponda a ele.

De qualquer forma, espero que isso ajude alguém,
Felicidades!

    
por 03.09.2011 / 23:06
4

Seu netcat está apenas lendo a saída do stdout do echo quando você usa pipe, ele não está mais "conectado" ao teclado. Para obter a resposta que você espera, você pode adicionar seus três "hello" a um arquivo executado

cat [myfile] | nc -u 127.0.0.1 5000
    
por 03.09.2011 / 22:45
2

Se você fizer um strace do escutar nc, ele mostrará que o netcat está aguardando a conexão e, uma vez obtido, se conectará a esse host e porta, ignorando todos os outros. Você precisa adicionar '-k' para continuar e '-w 0' para tempo limite de cada conexão após 0 segundos. Socat é uma escolha melhor, eu acho.

    
por 03.06.2016 / 04:25