transfert de fichiers fiable socat sur TCP

8

Je suis conscient des inconvénients de la conception "wait-> stop", qui est généralement proposée avec netcat:

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

(Ce n'est pas fiable: pas de compteur combien de temps vous attendez, il est toujours possible qu'il y ait un goulot d'étranglement du réseau pendant une seconde de plus. - Autre chose -> pourquoi attendre 10 secondes si vous pouvez savoir immédiatement que les données sont transférées et commencer à les traiter!)

Je voudrais une solution, avec une fermeture de flux tcp fiable et agréable .

J'ai trouvé socat, avec fermeture comme décrit dans man socat:

Lorsque l'un des flux atteint effectivement l'EOF, la phase de fermeture commence. Socat transfère la condition EOF à l'autre flux, c'est-à-dire qu'il essaie de ne fermer que son flux d'écriture, ce qui lui donne une chance de se terminer correctement.

J'ai trouvé que les commandes suivantes fonctionnaient:

Fichier d'envoi du serveur:

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

Serveur recevant le fichier:

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

Est-ce fiable? Peut-il être amélioré? (Ai-je utilisé les bonnes options? Y a-t-il de meilleures options à configurer? - Il y en a tellement avec socat)

Grzegorz Wierzowiecki
la source
Pour les adeptes, le deuxième exemple ("serveur recevant un fichier") est le client "typique" qui envoie un fichier à un serveur ... également les versions plus récentes de netcat ont une option "-N -q 0" qui devrait se traduire par une fiabilité accrue transferts que l'ancien mécanisme "attendre et espérer" :)
rogerdpack

Réponses:

6

Il me semble que votre cœur est solide - cela devrait être fiable et devrait se terminer une fois le fichier envoyé.

Si elle out.txtexiste déjà, cette configuration peut se comporter de manière inattendue. Si out.txtest plus long que test.txt, la dernière partie de out.txtrestera, car socat écrase le fichier octet par octet au lieu de s'assurer que le fichier est vide. Il existe plusieurs façons de résoudre ce problème, selon ce que vous voulez faire:

  • OPEN:out.txt,creat,truncsupprimera tous les octets out.txtavant d'écrire dessus. Cette option imite ce que vous attendez de cp, et c'est probablement ce que vous voulez.
  • OPEN:out.txt,creat,exclrefusera d'écrire out.txts'il existe déjà. Utilisez cette option pour plus de sécurité.
  • OPEN:out.txt,creat,appendajoutera des données à out.txt.

J'aime aussi courir md5sumsur les fichiers source et destination chaque fois que je bricole quelque chose comme ça ensemble, à cause de ce genre de cas d'angle.

Jander
la source
c'est génial que vous ayez mentionné "trunc" et ces cas de bord. Qu'en est-il de md5sum, dans mon cas, c'est un problème car j'ai besoin de transférer toutes les choses sans fermer la connexion ("one-shot";)). Même toi, c'est bon à mentionner pour les autres lecteurs :).
Grzegorz Wierzowiecki