Eu escrevi um pequeno servidor UDP no PHP que escuta em um soquete, aceita um comando e executa uma ação. É realmente muito básico. Eu posso conectar-me manualmente assim:
% nc -u host port
(onde nc = Ncat: Versão 7.50 ( link ))
Ao inserir comandos, vejo a resposta resultante. Ele funciona exatamente da maneira que eu quero que ele funcione na linha de comando.
No entanto, se eu simplesmente "cat" um arquivo assim:
cat FILE| nc -u host port
ou envie dados como este:
echo "command1\ncommand2\n" | nc -u host port
... então meu aplicativo PHP lê tudo, incluindo os caracteres de fim de linha, todos de uma vez. Eu só quero ler até o final da linha.
Claro, eu poderia envolver o conteúdo do arquivo e enviar cada linha para nc:
for x in 'cat <file>'; do
echo $x | nc -u host port
done
... mas isso é um completo desperdício. Eu quero 1 conexão para nc, não muitos.
Os caracteres EOL fazem isso na sequência porque, quando imprimo a saída no aplicativo PHP, vejo:
comando1
comando2
... mas está tudo em uma cadeia.
Por que o modo interativo está se comportando de maneira diferente do modo não interativo?
Eu tenho experimentado a tarde toda, e não consigo fazer isso funcionar.
Tenho certeza de que há uma explicação.
Obrigado por qualquer informação que você possa fornecer.
PS: O básico do código PHP é:
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_bind($sock, '0.0.0.0', 2000);
for (;;) {
socket_recvfrom($sock, $cmd, 1024, 0, $ip, $port);
echo "command is $cmd";
$reply = process($cmd);
echo "reply is $reply";
socket_sendto($sock, $reply, strlen($reply), 0, $ip, $port);
}
Ao inserir texto com nc interativamente, você pode pressionar CTRL-D para separar os pacotes. Se eu fizer a mesma coisa em um script de shell:
printf 'command1stdbuf -oL -eL cat FILE | nc -u host port
14commandd2for x in command1 command2; do
echo $x
sleep 1
done | nc -u host port
14'| nc -u host port
... todos os comandos aparecem como um comando.
Se eu reduzir o tamanho do pacote no código PHP para dizer 5 e, em seguida, enviar dados com 20 bytes, os dados serão truncados e não separados.
Eu também estou pronto on-line, isso pode ser um problema de buffering. Eu tentei usar:
% nc -u host port
... mas isso surpreendentemente não fez diferença.
Finalmente, descobri que, se eu fizer isso:
cat FILE| nc -u host port
... tudo corre conforme o planejado. O servidor recebe o primeiro comando e, em seguida, o segundo comando.
O que não está claro é por que o sono 1 faz a diferença. Retire e isso falhará. O acima é certamente melhor do que enviar cada eco para nc.