nc não está esperando pela desconexão do servidor no OS X

1

Como fazer o nc client no OS X Mavericks manter o soquete aberto e ler os dados até que o servidor desconecte o soquete?

Eu quero enviar dados para um servidor através de nc e depois usar a resposta. O problema é que nc desconecta o soquete após os dados terem sido enviados, sem esperar pela resposta do servidor.

Isso apenas gravará os dados e sairá:

$ echo "my instruction here" | nc 127.0.0.1 $MY_PORT

Isso gravará os dados e não sairá, mesmo que o servidor tenha sido desconectado:

$ cat <(echo "my instruction here") - | nc 127.0.0.1 $MY_PORT

A página nc man no OS X Mavericks tem o seguinte exemplo para enviar uma solicitação HTTP GET e imprimir a resposta, mas não está funcionando. Ele apenas envia a solicitação e sai sem aguardar a resposta do servidor. Parece que as informações da página do manual estão incorretas?

$ echo -n "GET / HTTP/1.0\r\n\r\n" | nc host.example.com 80
    
por Niklas Berglund 15.08.2014 / 13:57

3 respostas

0

Uma solução alternativa é continuar escrevendo algo no soquete - assim que os dados não puderem ser gravados, nc sairá.

(echo -ne "GET / HTTP/1.0\r\n\r\n"; (while true; do echo -e "\n"; sleep 1; done)) | nc example.com 80

Isso enviará uma linha vazia para nc uma vez por segundo até que nc não consiga gravar no soquete e nc saia.

Obrigado a Steffen Ullrich por sua resposta e comentários que me guiaram para essa solução.

    
por 16.08.2014 / 14:18
1

Assim que a escuta nc (servidor) for fechada, o cliente nc também será encerrado.

No Mac OS X, você pode open -a 'Activity Monitor' verificar isso.

O motivo pelo qual o nc & cat de exemplo trava não é nc , mas cat , que continua mantendo seu stdin e stdout abertos para leitura e gravação.

No entanto, quando cat tentar gravar no canal depois que a escuta nc tiver sido fechada, SIGPIPE será gerado e cat será encerrado.

# cat & SIGPIPE test
(sleep 1; echo hi) | 
   (trap 'echo "received signal $(($? - 128))" 1>&2' EXIT; cat) | :

kill -l 13
man bash | less -p 'EXIT STATUS'
man bash | less -Ip '128\+n'

Como uma alternativa para a solução alternativa de Niklas Berglund, é possível interceptar a saída do cliente nc para eliminar todo o grupo de processos, incluindo o comando cat pendente.

# console 1
# ctrl-c will "kill 0" entire process group sh -c '...'
nc -l 8080  

# console 2
# script command (FreeBSD version) will implicitly run: man 2 setsid
# kill 0 will therefore only kill the entire process group sh -c '...' 
# run in a script kill 0 would otherwise kill the entire script
# cf. also https://github.com/jerrykuch/ersatz-setsid 
script -q /dev/null sh -c '
(echo "my instruction here"; cat) | (trap "kill 0" EXIT; nc 127.0.0.1 8080)
'
    
por 15.10.2014 / 15:41
1

O comportamento padrão de nc é fechar a conexão se stdin for fechado. Para mudar você pode usar a opção -q (como -q -1 ) no Linux, pode ser a mesma no OS X. Veja a página man para detalhes.

Edit: parece que o OS X nc não suporta o switch -q ou algo similar. Nesse caso, você precisa ter certeza de que stdin não será fechado fazendo algo assim:

(eco "foo"; dormir 100000) | nc ...

    
por 15.08.2014 / 15:54