Envoi de fichier

Résolu
Messages postés
24
Date d'inscription
mardi 20 juillet 2004
Statut
Membre
Dernière intervention
8 juin 2011
-
Messages postés
24
Date d'inscription
mardi 20 juillet 2004
Statut
Membre
Dernière intervention
8 juin 2011
-
Bonjour,

j'ai un petit soucis conceptuel

Voilà, je dois faire un client / serveur capable d'envoyer des fichiers. J'étais donc parti sur l'idée d'envoyer mon fichier par trame de 1 ko selon le principe suivant :

Serveur envoie 1 Ko
Client traite les données puis envoie un accusé de réception (message "ok")
Serveur reçoit le message ok puis renvoie 1 ko
et ainsi de suite jusqu'à la fin.

Tout allait bien, les tests en local montraient des débits de 1 à 3 Mo/s ce qui était satisfaisant mais voilà.. sur internet c'est une toute autre histoire.

En effet, envoyer les données et recevoir l'accusé de réception prends environ 70 ms (à peine plus qu'un ping); du coup, je ne peux envoyer qu'une quinzaine de trame à la seconde soit un débit de .. 15 ko/s ce qui n'est pas acceptable.

Alors j'ai bien essayer de supprimer l'accusé de réception, le serveur envoie en boucle sans arrêt mais là curieusement, les données reçues côté client ne correspondent pas à ce qui a été envoyé; même problème si au lieu d'envoyer une trame de 1 ko, je l'aggrandit à 5...

Mes trames sont formées de la manière suivante :
Taille de la trame codée sur les 4 premiers bytes
Données de la trame codées sur le reste

Quand je dis que les données reçues ôté client ne correspondent pas à ce qui a été envoyé, je le vois du fait que la taille récupérée est complètement aberrante, le problème ne vient pas du fait qu'une trame soit reçue avant les trames précédentes (on sait pas ce qui peut se passer dans un réseau, mais c'est un problème que je gèrerai plus tard).

J'en viens donc à ma question, j'utilise des BufferedIn(Out)putStream, comment faire pour au choix 
- augmenter la taille d'une trame
- s'assurer que les données reçues soit bien les données envoyées

Ou sinon, plus généralement, comment on fait un client/serveur de fichier correct?

Merci d'avance

4 réponses

Messages postés
5367
Date d'inscription
dimanche 4 mai 2003
Statut
Modérateur
Dernière intervention
27 janvier 2022
111
Salut,

je viens de t'envoyer un mai avec un petit exemple de client serveur qui envoi un fichier que le serveur creer.

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

WORA
Messages postés
5367
Date d'inscription
dimanche 4 mai 2003
Statut
Modérateur
Dernière intervention
27 janvier 2022
111
Salut,

pour la taille des paquets voi les constructeurs

BufferedOutputStream(OutputStream out)


          Creates a new buffered output stream to write data to the
specified underlying output stream with a default 512-byte
buffer size.


BufferedOutputStream(OutputStream out,
                     int size)


          Creates a new buffered output stream to write data to the
specified underlying output stream with the specified buffer
size.

BufferedInputStream(InputStream in)


          Creates a
BufferedInputStream

and saves its argument, the input stream
in
, for later use.


BufferedInputStream(InputStream in,
                    int size)


          Creates a
BufferedInputStream

with the specified buffer size,
and saves its argument, the input stream
in
, for later use.

sinon pour des exemples de client/serveur d'envois  de fichiers regarde sur ce site il y en a

------------------------------------
"On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."

WORA
Messages postés
24
Date d'inscription
mardi 20 juillet 2004
Statut
Membre
Dernière intervention
8 juin 2011

Les constructeurs ne semblent pas suffisants ou ont leur limites :


je place size = 15*1024 + 4 pour le Output et l'Input (taille du tableau de byte que j'envoie)

Résultat :
mon serveur a envoyé en tout et pour tout 4 trames avant plantage.
le client en a reçu 7 avec des propriétés curieuses :

 - 1ere trame de 12708 byte (là logiquement, il renvoie ok au serveur)
 - 2e trame de 2656 (pareil il renvoie encore une fois ok .. notons que cette trame là est la différence entre ce qu'il aurait du recevoir et ce qu'il a effectivement reçu la première fois)

 - 3e trame de 12708, suivi de deux trames de 1412 et 1244

 - 6e trame de 4236 suivi de 5648

Le serveur a planté car il a reçu "okok" ce qui est considéré comme une erreur
Messages postés
24
Date d'inscription
mardi 20 juillet 2004
Statut
Membre
Dernière intervention
8 juin 2011

Merci bien, le fait de passer par des trames de 1 ko vient du fait que je dois avoir un controle total des débits de réception et d'envoi (au ko près), du coup j'envoyais mes trames tant que je ne dépassais pas mon débit, et je ne recevais que lorsque je n'avais pas reçu plus de données qu'autorisé à la seconde.

J'étais parti sur une bidouille là :

// Réception de la trame
size_msg = in.read(bufferReception, 0, bufferReception.length);


// S'assure que la trame est complète
int compteur = bufferReception.length - size_msg;
while (compteur > 0)
{
      byte[] b = new byte[compteur];
      int nb = in.read(b);
      
      for (int i = 0; i < nb; i++)
       bufferReception[size_msg + i] = b[i];
      
      compteur -= nb;
}

Bon ça marche (j'ai résumé là, la trame de fin est bien gérée) mais ça ressemble à rien, je vais plutot partir sur l'utilisation de available() et voir comment y adapter ma gestion de débit.

En tout cas, merci infiniment pour tes réponses à chaque fois :)