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.
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.
Le client: (ENVOIE DU FICHIER, ici nommé: "s.avi")
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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")
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 ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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"); } } }
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..
Partager