2010-09-17 10 views
0

Je suis en train d'écrire un serveur socket, que lorsque le client le demande, le serveur envoie des fichiers, les uns après les autres. Supose J'ai les fichiers 1, 2 et 3 à transférer. Comment puis-je savoir du côté client, si le fichier 1 a terminé et si file2 a démarré? Pour les messages, j'utilise un caractère DELIMITER (\ r \ n). Dois-je utiliser thise pour les fichiers aussi? Je ne pense pas que ce soit une bonne idée de continuer à regarder DELIMITER dans les octets du fichier.Transfert de plusieurs fichiers les uns après les autres - java sockets

Et j'ai besoin d'utiliser la même connexion TCP que les messages pour transférer ces fichiers.

+0

Un protocole standard est-il une option? Je recommande d'utiliser, par exemple, HTTP pour cela. – Kel

+0

non, c'est mon propre proto, et j'ai vraiment besoin d'utiliser le mien dans ce cas – fredcrs

+0

Néanmoins, réutiliser un protocole existant est une bien meilleure idée que de réinventer le vôtre. HTTP est un protocole mature et a couvert toutes les mises en garde que vous pouvez penser. Une alternative est FTP si votre seule intention est de transférer des fichiers. Un autre avantage est qu'il y a alors plus de choix d'API pour faciliter l'utilisation. – BalusC

Répondre

2

Il existe essentiellement deux façons de le faire:

  • Utilisez un caractère de séparation de fichiers, et mettent en place un mécanisme pour « échapper » le séparateur si elle apparaît dans le contenu d'un fichier.

  • Envoyez la longueur du fichier avant d'envoyer le fichier.

La première approche nécessite à la fois l'émission et la réception pour examiner chaque octet de chaque fichier transmis. La deuxième approche est meilleure car elle évite cela. Cependant, il suppose que vous pouvez déterminer la longueur du fichier avant de l'envoyer ... ce qui peut ne pas toujours être le cas; par exemple. si vous générez les fichiers à la volée, écrivez-les directement dans le flux de socket.

Il existe une variante de la seconde approche incarnée par le schéma "chunk encoding" de HTTP. (Merci @BalusC de me le rappeler.) Cela implique de diviser le fichier et de l'envoyer sous la forme d'une séquence de "morceaux" précédés par des tailles de blocs. Cela présente deux avantages par rapport à l'approche "taille + fichier":

  • L'expéditeur n'a pas besoin de connaître la taille du fichier auparavant.
  • Il est possible (avec une conception de protocole appropriée) que l'envoi ou le récepteur annule/saute l'envoi d'un fichier et continue avec le suivant. (Avec la simple « taille + fichier » approche, le protocole ne peut pas supporter cela parce que l'émetteur et le récepteur ne peut pas resynchroniser fiable.)
+0

Lorsque la longueur du fichier est inconnue, vous auriez utilisé [codage en bloc] (http://en.wikipedia.org/wiki/Chunked_transfer_encoding) dans HTTP. Il peut être utile de le copier/imiter. – BalusC

+0

@BalusC - bon point. –

1

Envoyer la longueur du fichier avant le contenu du fichier. De cette façon, le récepteur sait combien d'octets appartiennent à quel fichier.

1

Au lieu d'un délimiteur que vous pourriez avoir la réception de détecter lorsque le côté d'entrée de la prise est vide et envoie une requête à l'expéditeur du côté sortie du socket. Si c'était juste un retard, l'expéditeur répond avec 'envoi du fichier X' et le destinataire sait attendre. Si le transfert était terminé, l'expéditeur répond avec 'transfer complete (### bytes)' afin que le destinataire sache qu'il est prêt pour le fichier suivant.

Il ajoute un court délai entre les fichiers mais est un moyen simple d'utiliser le même socket pour plusieurs transferts sans avoir besoin d'utiliser des délimiteurs qui ont besoin d'être échappés.

+0

semble être une bonne idée, mais si c'était juste un retard, le serveur pourrait envoyer des octets du fichier avant de répondre à la requête. Imaginez: Il n'y a pas d'octets disponibles, le client demande si le fichier est terminé? Avant que le serveur reçoive le message, le délai est terminé et certains octets de fichiers arrivent, le client pense que c'est la réponse et non les octets du fichier, donc je vais devoir vérifier si ces octets sont une chaîne du serveur, rigt? – fredcrs

+0

Le client attend la réponse avant de décider si le fichier est terminé. Le serveur n'envoie plus de données jusqu'à ce que le client demande si le fichier a été fait. –

Questions connexes