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")

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");
		}
	}
 
}
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..