Transfert de fichiers

Ce document définit le protocole de transfert des fichiers ainsi que les classes qui lui sont associées.

Voir également : Transfert de fichiers simple.

Contraintes

  • Dans un soucis d'interopérabilité, le protocole est constitué de datagrammes et n’interagis pas directement avec le réseau.
  • Pour faciliter son implémentation, son utilisation et son débogage, le protocole n'utilisera que des chaines de caractères ASCII standard.
  • L'intégrité du fichier est vérifiée.

Protocole

  • L'expéditeur informe de la mise à disposition du fichier à un ou plusieurs clients.
  • Les destinataires intéressés demandent la taille et le nom du fichier, s'ils le souhaitent.
  • Les destinataires demandent ensuite les blocs dont ils ont besoin, dans la limite de 64 blocs (256ko).
  • L’expéditeur est passif, il ne fait que répondre aux demandes des destinataires.
  • L'expéditeur peut envoyer la totalité des blocs demandés mais n'est pas obligé.
  • Le destinataire peut demander la réémission des blocs.

Protocole côté destinataire

Le destinataire commence par demander la taille du fichier à transférer. Connaissant la taille du fichier, le destinataire sait quels sont les blocs à demander à l'expéditeur.

Toutes les 250 ms, le destinataire inscrit la suite du fichier jusqu'au premier bloc non reçu et fait une demande de 64 blocs de 4 ko (1 Mo/s).

Les blocs demandés doivent être judicieusement choisi pour éviter la réémission d'un bloc en cours d'émission. Il convient également de ne pas demander des blocs trop en avance pour ne pas gaspiller la mémoire.

Le chois des blocs est déterminé selon l'algorithme suivant :

  • Les 64 premiers blocs non reçus qui n'ont pas été demandés ces deux dernières secondes.

Pendant le transfert, le client attend derrière un maximum de 2 Mo contenu dans une fenêtre qu'il conviendra de choisir ni trop grande, ni trop petite :

  • Si la fenêtre est trop grande, le destinataire gaspille de la mémoire.
  • Si la fenêtre est trop petite, le débit de transfert sera affecté par la perte de paquets.

Une fenêtre de 1024 blocs (4 Mo) devrait être un bon compromis.

Les données reçues sont stockées dans un std::map<uint32, std::string> pour faciliter leur manipulation. L'ajout d'un bloc s'effectue par l'opérateur std::map::operator[] seulement s'il est attendu. Un bloc ajouté au fichier est détruit par la méthode std::map::erase().

Protocole côté expéditeur

Lorsque l'expéditeur reçois une demande, il y répond immédiatement s'il s'agit d'une demande de nom ou de taille de fichier. S'il s’agit d'une demande de blocs, l'expéditeur les mémorisent pour les envoyer plus tard en prenant soin de ne pas enregistrer de doublons.

Toutes les 16 ms, 5 blocs demandés sont émis et retiré du tableau des demandes.

Les blocs demandés sont enregistrés dans un std::set<uint32>.

Exemples de trames d'informations

Mise à disposition d'un fichier

Trame émise par l’expéditeur lors de la mise à disposition du fichier :

MISE_A_DISPOSITION 80e75c349ff1c6227a0ee9b935e6ee8b

Cette trame comporte la signature MD5 du fichier mis à disposition.

Demande de la taille du fichier

DEMANDE_TAILLE 80e75c349ff1c6227a0ee9b935e6ee8b

Réponse comportant la taille en octets.

REPONSE_TAILLE 80e75c349ff1c6227a0ee9b935e6ee8b 5024691

Demande du nom du fichier

DEMANDE_NOM 80e75c349ff1c6227a0ee9b935e6ee8b

Réponse comportant le nom du fichier.

REPONSE_NOM 80e75c349ff1c6227a0ee9b935e6ee8b Renaud - Lola.mp3

Exemples de trames de transfert

Le destinataire demande les blocs dont il a besoin.

DEMANDE_BLOC 80e75c349ff1c6227a0ee9b935e6ee8b 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

L'expéditeur envoi les blocs demandés, par bloc de 4096 octets.

REPONSE_BLOC 80e75c349ff1c6227a0ee9b935e6ee8b 1 hSOAji7f9k7f1nZf+P+1Nb415X6VJb5lzPn3K8n3Lcn3Lyn2LysNrKgIrK4NbmgMV44Aorv2lu/b...
REPONSE_BLOC 80e75c349ff1c6227a0ee9b935e6ee8b 2 v9Ld0yYx2WF3untOgX9ZZXhtY3RzW0xTR0xje0xDW3R9a3QdnP/m6JrmmKqmaFDZGF3RGF3ewE4B...
REPONSE_BLOC 80e75c349ff1c6227a0ee9b935e6ee8b 3 KpriKptjK5vjKpqhAO72gzhQxpz8+FI47fDYG+H8u0SkJOMu+f8lDcDoCED0+cVvBGgombP82Yf8...

L'expéditeur est passif : il ne fait que répondre aux demandes du destinataire.

Encodage de l'information

Le fichier à transférer est encodé en base64.

Vérification de l'intégrité du fichier

L'intégrité du fichier transféré est vérifiée en comparant les empreintes numériques des fichiers source et destination à l'aide de l'algorithme MD5.