Socket et Transfert de fichiers
Bonsoir à tous ;)
Je suis nouveau sur developpez.com, et si je post c'est vraiment parce que je suis bloqué de chez bloqué.
La situation: J'ai fais un petit programme d'entrainement permettant le transfert de fichiers, aussi bien binaire que text, de toute manière ça n'a pas d'importance, je gère les fichier avec des flux binaire :ccool:.
Le problème, c'est que l'envoie de fichier trop volumineux nécessite l'envoie par packets! J'ai donc utilisé un buffer de 4096 bytes.
Ainsi pas de problème, je parviens bien à transférer le fichier entre le client et le serveur mais, lorsque je reçois le fichier à l'arrivé, ce dernier est 8 fois sur 10 corrompu :(.
En effet, son volume est supérieur au fichier original de quelque octets!
Si vous pouvez m'aidez ce serai vraiment sympa:
Précision sur le code: utilise uniquement la bibliothèque standard et swing pour le GUI, donc rapide si vous voulez tester pour m'aider :mouarf:.
Le client: (ENVOIE DU FICHIER, ici nommé: "s.avi")
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
| import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.text.DecimalFormat;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
public class Foo extends JFrame{
private JProgressBar load;
private JButton launch;
private JLabel dl =new JLabel();
public static final int BUFFER_SIZE =4096;
public static void main(String args[]) throws InterruptedException{
//EXEC PROGRAMME
new Foo();
}
public Foo() throws InterruptedException{
//INIT GUI
this.setSize(400, 200);
this.setTitle("DownLoad File");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.load =new JProgressBar();
this.load.setMaximum(100);
this.load.setMinimum(0);
this.load.setStringPainted(true);
this.getContentPane().add(this.load, BorderLayout.CENTER);
this.launch =new JButton("Send");
//LANCER TRANSFERT DU FICHIER(DANS UN THREAD) AU CLICK DU BUTTON
this.launch.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
new Thread(new Traitement()).start();
}
});
this.getContentPane().add(launch, BorderLayout.SOUTH);
this.dl.setText("Téléchargé: ");
this.getContentPane().add(dl, BorderLayout.NORTH);
this.setVisible(true);
}
public class Traitement implements Runnable{
@Override
public void run(){
Foo.this.launch.setEnabled(false);
BufferedInputStream bis =null;
try{
//OUVERTURE EN LECTURE DU FICHIER @ ENVOYER
bis =new BufferedInputStream(
new FileInputStream(
new File("s.avi")));
//EXCEPTION NON GéRé
}catch(FileNotFoundException e){}
Socket sock;
try{
//INIT VARS
sock = new Socket("127.0.0.1", 22000);
//ECRIRE SUR LA SOCKET
BufferedOutputStream bos =new BufferedOutputStream(sock.getOutputStream());
DecimalFormat formater =new DecimalFormat("0.##");
byte buffer[] =new byte[Foo.BUFFER_SIZE];
float s, kodl;
int i =0;
Foo.this.load.setMaximum((int)(s =bis.available()));
s /=1000000;
long start =System.currentTimeMillis();
//ENVOIE DU FICHIER
while(bis.read(buffer) !=-1){
bos.write(buffer);
bos.flush();
i +=Foo.BUFFER_SIZE;
//AFFICHAGE GUI
Foo.this.load.setString(formater.format((float)i /1000000) +"/" +formater.format(s) +" Mo vitesse de dl: " +formater.format(kodl =((float)i /1000 /((System.currentTimeMillis() -start) /1000))) +" Ko/s Tps estimé: " +(int)((s *1000) /kodl) +" sec");
Foo.this.dl.setText("@Télécharger: " +formater.format((float)bis.available() /1000000) +" Mo " +" En téléchargement depuis: " +(System.currentTimeMillis() -start) /1000 +" sec");
Foo.this.load.setValue(i);
}
//AFFICHAGE GUI
Foo.this.dl.setText("Téléchargé en: " +(System.currentTimeMillis() -start) /1000 +" sec");
Foo.this.load.setString("Téléchargement Terminé!");
//FERMETURE STREAM
bis.close();
bos.close();
sock.close();
//EXCEPTION NON GéRéeS
}catch (UnknownHostException e){
}catch (IOException e){}
System.out.println("FICHIER TRANSFERé");
Foo.this.launch.setEnabled(true);
}
}
} |
Le serveur: (RéCEPTION du fichier "s.avi")
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.net.ServerSocket;
import java.net.Socket;
public class Foo{
public static final int BUFFER_SIZE =4096;
public static void main(String argv[]) throws IOException{
//SERVEUR GERE UNIQUEMENT 1 CONNECTION A LA FOIS
//ACCEPTE UNE NOUVELLE CONNECTION A LA RECEPTION COMPLETE DU FICHIER
while(true){
System.out.println("Serveur lancé!");
ServerSocket ssock =new ServerSocket(22000, 1);
Socket csock =ssock.accept();
System.out.println("Une connexion entrante...\n\tRéception du fichier en cours...");
//LECTURE DU SOCKET
BufferedInputStream bis =new BufferedInputStream(csock.getInputStream());
//ECRITURE DANS LE NOUVEAU FICHIER
BufferedOutputStream bos =new BufferedOutputStream(
new FileOutputStream(
new File("s.avi")));
byte buf[] =new byte[Foo.BUFFER_SIZE];
//RéCEPTION DU FICHIER
while(bis.read(buf) !=-1){
bos.write(buf);
bos.flush();
}
//FERMETURE STREAM
bos.close();
bis.close();
ssock.close();
csock.close();
System.out.println("Fichier réceptionné !\n\n");
}
}
} |
C'est donc lors de l'envoie: confer ligne commenté de mon code: "//ENVOIE DU FICHIER" et "//RéCEPTION DU FICHIER" que je dois oublier de faire un contrôle ou autres choses... Mais quoi ?
Merci d'avance pour votre précieuse aide, car malgré mes nombreuses recherchse, je n'ai rien trouvé de fonctionnel, ou qui pourrai apporter de nouvelles pistes! Hormis sur un forum ou quelqu'un proposait de faire un accusé de réception afin de vérifier l'ordre de réception des données et leur intégrité, mais les protocoles TCP/IP s'occupent de gérer cela il me semble.
De plus j'ai essayé avec la méthode available() de l'objet InputStream/BufferedInputStream pour boucler dessus mais le résultat est le même qu'avec la méthode read() utilisé ici dans l'exemple de mon code ci-dessus.
PS: le code n'est pas optimisé: exceptions non gérées, etc..