Bonjour !

J'essaie de coder un petit logiciel client/serveur pour envoyer des fichiers à travers un réseau.
J'ai un souci avec les flux, je pense que je m'y prend mal à ce niveau là. Je souhaite envoyer plusieurs fichiers et j'ai une exception lorsque j'essaie d'envoyer le deuxième fichier (pour le premier il n'y a à priori pas de problèmes).

Pour envoyer un fichier (partie client) je procède de la façon suivante :
- Creation d'un socket
- Récupération de l'OutputStream du socket
- Création d'un DataOutputStream à partir de l'OutputStream du socket
- Récupérer la liste des fichiers à envoyer

Puis, pour chaque fichier on envoie un code au serveur qui précise qu'on envoie un fichier, on envoie le nom du fichier à transférer et on envoie son contenu :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
private void sendFile(final DataOutputStream dos, final File file) throws IOException {
		dos.writeUTF("file");	//On précise qu'on envoie un fichier
		dos.writeUTF(file.getName());	//On envoie le nom du fichier
		dos.writeInt(new Long(file.length()).intValue());	//On envoie la taille du fichier
		writeFile(dos, file);								//On envoie le contenu du fichier
	}
Au cas où, voici la fonction writeFile() :

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
private void writeFile(final OutputStream os, final File file) throws IOException {
		// Declaration et ouverture des flux
		FileInputStream sourceFile = new FileInputStream(file);
 
		try {
			DataOutputStream destinationFile = null;
			destinationFile = new DataOutputStream(os);
 
			// Lecture par segment de 0.5Mo
			byte buffer[] = new byte[512 * 1024];
			int nbLecture;
 
			while ((nbLecture = sourceFile.read(buffer)) != -1) {
				destinationFile.write(buffer, 0, nbLecture);
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		} finally {
			if (sourceFile != null) {
				sourceFile.close();
			}
		}
	}
Pour la partie Serveur, dès qu'une connexion est initiée j'ouvre un Thread qui va s'occuper de servir le client. Voici la méthode run() de mon Thread :

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
@Override
	public void run() {
		try {
			DataInputStream dis = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
			String command = getCommand(dis);
 
			while (command.equals("file")) {
				processFile(dis);
				command = getCommand(dis);
			}
 
			socket.close();
		} catch (IOException ex) {
			// TODO Auto-generated catch block
			ex.printStackTrace();
		}
	}
Voici le code de la méthode processFile() :

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
public void processFile(final DataInputStream dis) throws IOException {
		File f = null;
		FileOutputStream fos = null;
 
		try {
			String filename = getFileName(dis);
			System.out.println("Receiving : " + filename);
			f = new File(filename);
			fos = new FileOutputStream(f);
			fos.write(readData(dis, getFileSize(dis)));
 
		} catch (IOException ex) {
			ex.printStackTrace();
		} finally {
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException ex) {
					// TODO Auto-generated catch block
					ex.printStackTrace();
				}
			}
		}
	}
Les différentes méthodes getCommand(), getFileSize() et getFileName() renvoient simplement le résultat de DataInputStream.readUTF() quand on lit une String, ou DataInputStream.readInt() pour lire la taille du fichier.

L'exception se produit côté serveur lors du second appel à getCommand(), dans la boucle while, l'erreur renvoyée est la suivante :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
java.io.UTFDataFormatException: malformed input around byte 4
Je suis un peu perdu avec tous les types de flux disponibles, je me demande si ma façon de procéder est vraiment optimale. Ce que je souhaite c'est avoir de la souplesse pour envoyer mes données et dans la mesure du possible de traiter qu'avec une seule classe de flux (DataInputStream et DataOutputStream me semble assez pratique pour s'échanger des types différents).

Merci d'avance pour votre aide