Envoi des fichiers par des sockets java [Résolu/Fermé]

Signaler
-
Messages postés
16372
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
23 juillet 2021
-
salut, pour mon projet je dois implémenter une application web qui servira à l'envoi des images et du sons, pour cela j'ai utilisé les sockets en JAVA j'ai mes codes qui marchent parfaitement coté serveur et coté client, je fais le RUN tout se passe bien et mon fichier, une fois reçue par mon serveur il est bien créé mais quand je le consulte je ne le trouve pas en totalité ( pour le son seulement quelques secondes sont jouées et parfois non executable, pour l'image, elle ne s'affiche pas il n'y a q'un croix rouge ) veuillez m'aider S.V.P et merci
et voila mes codes :
Côté Client:
public class Client {

public static void main(String[] zero) throws IOException {

File f = new File("C:\\Users\\Douda\\Downloads\\musicmp4.MP4");
if(f.exists())
{
System.out.println("Envoi du fichier "+f.toURI().toURL());
Socket s = new Socket(InetAddress.getLocalHost(),9001);

OutputStream fluxsortie = s.getOutputStream();

long taillefichier =f.length();

System.out.println("Taille : "+ taillefichier);

long nbpassagesuposé=taillefichier / 4096;

System.out.println("Passages supposés : "+nbpassagesuposé);

InputStream in = new BufferedInputStream(new FileInputStream(f));
ByteArrayOutputStream tableaubytes = new ByteArrayOutputStream();
BufferedOutputStream tampon = new BufferedOutputStream(tableaubytes);

int lu = in.read();
int[] aecrire = new int[4096];
int compteur = 0;
long ouonestrendu=0;

//Tant qu'on est pas à la fin du fichier
while(lu > -1)
{
//On lit les données du fichier
aecrire[compteur] = lu;
lu = in.read();
compteur++;


//Quand on a rempli le tableau, on envoie un paquet de 4096 octets
if(compteur == 4096)
{
compteur=0;
ouonestrendu++;
//On remplit le tampon
for(int x=0;x<4096;x++)
tampon.write(aecrire[x]);

//Et on l'envoie
byte[] b=tableaubytes.toByteArray();
tampon.write(b);
tampon.flush();

tableaubytes.reset();
System.out.println("Avancement : "+(float) ouonestrendu/nbpassagesuposé * 100+"%");
}
}

//On envoie le dernier paquet, qui ne fait pas forcément 4096 octets
//On remplit le tampon
for(int x=0;x<compteur;x++)
tampon.write(aecrire[x]);

//Et on l'envoie
tampon.flush();
fluxsortie.write(tableaubytes.toByteArray());
fluxsortie.flush();

System.out.println("Avancement: "+(float) ouonestrendu/nbpassagesuposé * 100+"%");

System.out.println("Youpi finished");
in.close();
tampon.close();
System.out.println("Passages effectués : "+ouonestrendu);
s.close();
}
else
{
System.out.println("Le fichier "+f+" est introuvable");
}

}

}
-----------------------------
*****************************
Coté Serveur:

public class Serveur {

public static void main(String[] zero) throws IOException {


//On attend la connexion d'un client
ServerSocket socketserver= new ServerSocket(9001);
Socket serviceSocket = socketserver.accept();


int lu;


//Création de l'entrée
InputStream inpute = serviceSocket.getInputStream();

OutputStream out = new FileOutputStream("C:\\musicmp4.MP4");

//Reçoit du client
BufferedInputStream inBuffer = new BufferedInputStream(inpute);

//Envoi vers le fichier
BufferedOutputStream outBuffer = new BufferedOutputStream(out);

lu = inBuffer.read();

int compteur = 0;

while(lu > -1)
{
outBuffer.write(lu);
lu = inBuffer.read();

compteur++;
}

outBuffer.write(lu);

outBuffer.flush();
outBuffer.close();
inBuffer.close();

out.flush();
out.close();
inpute.close();
serviceSocket.close();

}
}





<config,g>Windows 7 / Safari 535.1</config>

6 réponses

Messages postés
16372
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
23 juillet 2021
2 858
Bon j'ai regardé ton code, le moins qu'on puisse dire c'est que tu te compliques la vie !
En particulier, pourquoi as-tu besoin d'ouvrir autant de flux ?

Voici le coeur du programme, tu vas voir qu'en fait c'est très simple !

public class Commun
{
    public static void transfert(InputStream in, OutputStream out, boolean closeOnExit) throws IOException
    {
        byte buf[] = new byte[1024];
        
        int n;
        while((n=in.read(buf))!=-1)
            out.write(buf,0,n);
        
        if (closeOnExit)
        {
            in.close();
            out.close();
        }
    }
}

public class Client
{
    public static void main(String...args) throws IOException 
    { 
        Socket sock = new Socket(InetAddress.getLocalHost(),9001);
    
        Commun.transfert(
                new FileInputStream("D:\\test.jpg"),
                sock.getOutputStream(),
                true);
        
        sock.close();
    } 
}

public class Serveur
{
    public static void main(String...args) throws IOException 
    { 
        Socket sock = new ServerSocket(9001).accept();
        
        Commun.transfert(
                sock.getInputStream(),
                new FileOutputStream("D:\\test2.jpg"),
                true);
        
        sock.close(); 
    } 
}
28
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 65492 internautes nous ont dit merci ce mois-ci


merciiiiiiiiiiiiiiiiiiiiiiiiiiiii c'est trop mignon, court, et bien développé, et ça marche parfaitement :)
merci
Mais moi je le lane comment ceci?
Et puis, drvrai-je mettre chaque classe ainsi décrite dans un fichier .java séparément?
Messages postés
16372
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
23 juillet 2021
2 858
Oui chaque classe dans un fichier .java séparé, et après tu lances la classe serveur puis la classe client dans deux fenêtres distinctes.
Messages postés
2295
Date d'inscription
mercredi 25 février 2009
Statut
Membre
Dernière intervention
22 juillet 2019
198
t es sur qu il faut pas passer tes buffers en hexa ???
Et ta boucle d'arret doit se faire avec un code d'echappement, si mes souvenirs sont bon.
Par exemple un buffer d'une certaine taille avec des carracteres a la manque dedans ...
tu peux aussi rajouter un correcteur d erreur sur ta trame comme une somme que tu envoies soit à la fin soit comme nouvelle trame ...
Differents modèles de protocoles te permettent de jongler sur ces echanges ...
par exemple, renvoie de la trame si elle est fausse ou intercepté ...
ce sujet date, juste pour ajouter pour ceux qui cherchent:

La fonction transfert bug parfois en fonction des extensions, et la boucle ne donne jamais comme résultat -1... mieux vaut utiliser:

public static void transfert(InputStream in, OutputStream out, boolean closeOnExit) throws IOException {
        byte buf[] = new byte[1024];
        
        int n;
        while((n=in.read(buf))==1024){
            out.write(buf,0,n);
        }
        //et la on ajoute les bytes plus petits que 1024 ) la fin
        out.write(buf,0,n);
        if (closeOnExit) {
            in.close();
            out.close();
        }
    }
Messages postés
16372
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
23 juillet 2021
2 858
Bonjour,

Tu pars du principe que si la lecture ne renvoit pas 1024 alors c'est la fin. Or il peut y avoir moins de 1024 octets une fois, voire même 0, et pourtant la lecture n'est pas terminée. Cela peut venir d'une latence sur le réseau (ce qui se passerait par exemple si tu téléchargeais un fichier sur internet) ou alors d'une attente à l'autre bout du canal de communication.
Le seul moyen de garantir que la communication est vraiment terminée c'est le -1 (c'est écrit dans la documentation de la méthode read), si tu n'as jamais -1 c'est parce que le flux est resté ouvert du côté de l'écriture. Typiquement si tu lis directement sur System.in, le flux du clavier, celui-ci ne se ferme jamais tout seul, et tu pourrais le lire indéfiniment sans avoir de -1, et lorsque plus rien n'est écrit, tu as 0 octets lus pendant longtemps, mais dès que retapes à nouveau sur le clavier, tu recommences à lire des données...

PS. J'ai modifié ton message pour rajouter les balises de codes : <code java></code>
Re-Bonjour.

C'est vrai...

Merci de ton aide...
et la class Commun on en fait quoi ?
Messages postés
16372
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
23 juillet 2021
2 858
Bonjour,

C'est quoi ton problème avec la classe Commun ?
Messages postés
17
Date d'inscription
mardi 19 mai 2015
Statut
Membre
Dernière intervention
11 août 2015

Bonjour...
Bien que ce sujet doive être enterré... pour ceux qui cherchaient (comme moi) à transférer un fichier d'un client au serveur, qui le retransmettait à un client, sans fermer des sockets, je me suis contenté d'un code comme ça:

Client envoyeur:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;

public class Transfert {
    public static void transfert(InputStream in, OutputStream out) throws IOException {
        byte buf[] = new byte[1024];
        
        int n;
        while((n=in.read(buf))!=-1){
            out.write(buf,0,n);
        }
        PrintWriter outp = new PrintWriter(out);
  outp.println("!§#%%123{#done#}123%%#§!");
  outp.flush();
    }
}



Serveur:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;

public class Transfert {
 
    public static void transfert(InputStream in, OutputStream out){
        byte buf[] = new byte[1024];
        
        int n;
        try {
         boolean cont = true;
   while(cont){
    n = in.read(buf);
       out.write(buf,0,n);
       if(isEndReached(buf)){
        cont = false;
       }
   }
   PrintWriter outp = new PrintWriter(out);
   outp.println("!§#%%123{#done#}123%%#§!");
   outp.flush();
  } catch (IOException e) {
   e.printStackTrace();
  }
    }
    
    private static String GetString(byte[] bytes){
        return new String(bytes);
    }
    
    private static boolean isEndReached(byte[] buf){
     if(GetString(buf).contains("!§#%%123{#done#}123%%#§!")){
      return true;
     }
     return false;
    }
    
}



Le client recepteur:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class Transfert {
 
    public static void transfert(InputStream in, OutputStream out){
        byte buf[] = new byte[1024];
        
        int n;
        try {
         boolean cont = true;
   while(cont){
    n = in.read(buf);
       out.write(buf,0,n);
       if(isEndReached(buf)){
        cont = false;
       }
   }
  } catch (IOException e) {
   e.printStackTrace();
  }
    }
    
    static String GetString(byte[] bytes){
        return new String(bytes);
    }
    
    public static boolean isEndReached(byte[] buf){
     if(GetString(buf).contains("!§#%%123{#done#}123%%#§!")){
      return true;
     }
     return false;
    }
    
}


Beaucoup trouverons à redire de ce code, mais il remplit parfaitement sa fonction :)
Messages postés
5
Date d'inscription
dimanche 29 septembre 2013
Statut
Membre
Dernière intervention
30 juin 2015

Salut ! Omment est ce qu'on doit proceder s'il ya plusieur client et qu'on veut envoyer le fichier a un client precis ?
Merci
Messages postés
16372
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
23 juillet 2021
2 858 >
Messages postés
5
Date d'inscription
dimanche 29 septembre 2013
Statut
Membre
Dernière intervention
30 juin 2015

Bonjour,

Soit le "client" récepteur utilise le code du serveur pour obtenir le fichier.
Soit le serveur stocke le fichier envoyé avant de le transférer.
est il possible d'accelerer et de reduire le transfert des donnees via UDP Socket avec Java. Si ou comment? pardon exemple concret.
Merci
Messages postés
16372
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
23 juillet 2021
2 858
Bonjour,

Un bon début pour réduire le (temps ? volume ?) des données, c'est de considérer des ZipInputStream et ZipOutputStream qui vont compresser les données, ce qui a évidemment un coût en terme de calcul à l'envoi et à la réception des données, mais permet de gagner sur le transfert des données en soit.

Sinon pour UDP vs TCP regarde cet article : TCP / UDP : Quelles différences ?