transferência confiável de arquivos socat sobre TCP

8

Estou ciente das desvantagens do design "wait-> stop", que geralmente são propostas com o netcat:

server$ cat test.dat | nc -q 10 -l -p 7878
client$ nc -w 10 remotehost 7878 > out.dat

(Não é confiável: não importa quanto tempo você espera, sempre é possível que exista um gargalo na rede por mais um segundo. - Outra coisa -> por que esperar 10 segundos se você pode saber imediatamente que os dados são transferidos e começar a processá-los!)

Eu gostaria de uma solução, com fechamento de fluxo tcp confiável e agradável .

Eu encontrei socat, com fechamento como descrito em man socat:

Quando um dos fluxos atinge efetivamente o EOF, a fase de fechamento começa. O Socat transfere a condição EOF para o outro fluxo, ou seja, tenta desligar apenas seu fluxo de gravação, dando a chance de terminar normalmente.

Encontrei os seguintes comandos funcionando:

Servidor enviando arquivo:

server$ socat -u FILE:test.dat TCP-LISTEN:9876,reuseaddr
client$ socat -u TCP:127.0.0.1:9876 OPEN:out.dat,creat

Servidor que recebe o arquivo:

server$ socat -u TCP-LISTEN:9876,reuseaddr OPEN:out.txt,creat && cat out.txt
client$ socat -u FILE:test.txt TCP:127.0.0.1:9876

É confiável? Pode ser melhorado? (Eu usei as opções corretas? Existem opções melhores para configurar? - Existem muitas delas com socat)

Grzegorz Wierzowiecki
fonte
Para os seguidores, no segundo exemplo ("servidor que recebe o arquivo"), existe o cliente "típico" enviando um arquivo para um servidor ... também as versões mais recentes do netcat têm a opção "-N -q 0", que deve resultar em mais confiabilidade transferências do que o velho "espera e esperança" mecanismo :)
rogerdpack

Respostas:

6

Parece-me que seu núcleo é sólido - isso deve ser confiável e sair quando o arquivo tiver sido completamente enviado.

Se out.txtjá existir, no entanto, essa configuração pode se comportar inesperadamente. Se out.txtfor maior que test.txt, a última parte out.txtpermanecerá, pois o socat está substituindo o arquivo byte por byte em vez de garantir que o arquivo esteja vazio. Existem algumas maneiras de corrigir isso, dependendo do que você deseja fazer:

  • OPEN:out.txt,creat,truncexcluirá todos os bytes out.txtantes de gravá-lo. Essa opção imita o que você esperaria cpe provavelmente é o que você deseja.
  • OPEN:out.txt,creat,exclse recusará a escrever out.txtse ele já existir. Use esta opção para segurança extra.
  • OPEN:out.txt,creat,appendanexará dados a out.txt.

Também gosto de rodar md5sumnos arquivos de origem e de destino sempre que juntar algo assim, por causa desses tipos de casos de canto.

Jander
fonte
é ótimo que você mencionou sobre "trunc" e esses casos extremos. E o md5sum, no meu caso, é um problema, porque eu preciso transferir todas as coisas sem fechar a conexão ("one-shot";)). Mesmo tu, é bom mencionar para outros leitores :).
Grzegorz Wierzowiecki