Envoi des fichiers par des sockets java

Résolu/Fermé
tissouassoum - 23 août 2011 à 00:31
KX Messages postés 16664 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 21 janvier 2023 - 30 juin 2015 à 07:01
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

KX Messages postés 16664 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 21 janvier 2023 2 999
23 août 2011 à 10:32
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
tissouassoum
23 août 2011 à 13:01
merciiiiiiiiiiiiiiiiiiiiiiiiiiiii c'est trop mignon, court, et bien développé, et ça marche parfaitement :)
merci
0
Mais moi je le lane comment ceci?
Et puis, drvrai-je mettre chaque classe ainsi décrite dans un fichier .java séparément?
0
KX Messages postés 16664 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 21 janvier 2023 2 999
26 nov. 2011 à 15:13
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.
0
Fallentree Messages postés 2295 Date d'inscription mercredi 25 février 2009 Statut Membre Dernière intervention 22 juillet 2019 208
Modifié par Fallentree le 23/08/2011 à 00:45
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é ...
0
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();
        }
    }
0
KX Messages postés 16664 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 21 janvier 2023 2 999
Modifié par KX le 2/01/2015 à 17:37
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>
-1
Re-Bonjour.

C'est vrai...

Merci de ton aide...
0
et la class Commun on en fait quoi ?
0
KX Messages postés 16664 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 21 janvier 2023 2 999
25 févr. 2015 à 10:55
Bonjour,

C'est quoi ton problème avec la classe Commun ?
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
gpotter2 Messages postés 17 Date d'inscription mardi 19 mai 2015 Statut Membre Dernière intervention 11 août 2015
Modifié par gpotter2 le 19/05/2015 à 22:23
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 :)
0
pipo91 Messages postés 5 Date d'inscription dimanche 29 septembre 2013 Statut Membre Dernière intervention 30 juin 2015
30 juin 2015 à 06:21
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
0
KX Messages postés 16664 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 21 janvier 2023 2 999 > pipo91 Messages postés 5 Date d'inscription dimanche 29 septembre 2013 Statut Membre Dernière intervention 30 juin 2015
30 juin 2015 à 07:01
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.
0
est il possible d'accelerer et de reduire le transfert des donnees via UDP Socket avec Java. Si ou comment? pardon exemple concret.
Merci
0
KX Messages postés 16664 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 21 janvier 2023 2 999
30 mai 2015 à 14:47
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 ?
0